Findall with array of string groovy - groovy

I have a string /sample/data. When I split using split I get the following result,
["","sample","data"]
I want to ignore the empty string(s). So I tried the following code,
"/sample/data".split('/').findAll(it != "")
It gives me an error "cannot call String[] findAll with argument bool".
How can I split and get a List without empty string in it?

split method returns array.
If you need List, use tokenize
"/sample/data".tokenize('/')
also you don't need to use findAll in this case.

You can do as below:
println "/sample/data".split('/').findAll {it}
findAll {it} would fetch all the non empty values.

Parens would work (see comments on question). So your solution is already close:
"/a/b".split("/").findAll()
Because most of the Groovy functions have a zero arity, which will call the function with an identity closure. And since an empty string is considered falsey, this will filter them out.

Related

Check if string is in list with python

I'm new to python, and I'm trying to check if a String is inside a list.
I have these two variables:
new_filename: 'SOLICITUDES2_20201206.DAT' (str type)
and
downloaded_files:
[['SOLICITUDES-20201207.TXT'], ['SOLICITUDES-20201015.TXT'], ['SOLICITUDES2_20201206.DAT']] (list type)
for checking if the string is inside the list, I'm using the following:
if new_filename in downloaded_files:
print(new_filename,'downloaded')
and I never get inside the if.
But if I do the same, but with hard-coded text, it works:
if ['SOLICITUDES2_20201206.DAT'] in downloaded_files_list:
print(new_filename,'downloaded')
What am I doing wrong?
Thanks!
Your downloaded_files is a list of lists. A list can contain anything insider it, numbers, list, dictionaries, strings and etc. If you are trying to find if your string is inside the list, the if statement will only look for identical matches, i.e., strings.
What I suggest you do is get all the strings into a list instead of a list of lists. You can do it using list comprehension:
downloaded_files = [['SOLICITUDES-20201207.TXT'], ['SOLICITUDES-20201015.TXT'], ['SOLICITUDES2_20201206.DAT']]
downloaded_files_list = [file[0] for file in downloaded_files]
Then, your if statement should work:
new_filename = 'SOLICITUDES2_20201206.DAT'
if new_filename in downloaded_files_list:
print(new_filename,'downloaded')
Your code is asking if a string is in a list of lists of a single string each, which is why it doesn't find any.

ADF expression to convert array to comma separated string

This appears to be pretty basic but I am unable to find a suitable pipeline expression function to achieve this.
I have set an array variable VAR1 with the following value, which is an output from a SQL Lookup activity in an ADF pipeline:
[
{
"Code1": "1312312"
},
{
"Code1": "3524355"
}
]
Now, I need to convert this into a comma separated string so I can pass it to a SQL query in the next activity - something like:
"'1312312','3524355'"
I am unable to find an expression function to iterate over the array elements, nor convert an array to a string. The only pipeline expression functions I see are to convert string to array and not the other way around.
Am I missing something basic? How can this be achieved?
Use 'join' function present in 'collection' functions in 'Add dynamic content'. For example:
join(variables('ARRAY_VARIABLE'), ',')
I had this same issue and was not totally satisfied just using the join function because it keeps the keys from the json object. Also, using an iterator approach can work but is needlessly expensive and slow if you have a long list. Here was my approach, using join and replace:
replace(replace(join(variables('VAR1'), ','), '{"Code1":', ''), '}', ''))
This will give you exactly the output you are looking for.
I got it working using a ForEach loop activity to iterate over my array and use a Set Variable task with a concat expression function to create my comma separated string.
Wish they had an iterator function in the expression language itself, that would have made it much easier.
In case, you just have two elements in the array, then you can do something like:
#concat(variables('variable_name')[0].Code1, ',', variables('variable_name')[1].Code1)

Kotlin method chaining to process strings in a list

I have a list of strings I get as a result of splitting a string. I need to remove the surrounding quotes from the strings in the list. Using method chaining how can I achieve this? I tried the below, but doesn't work.Says type interference failed.
val splitCountries: List<String> = countries.split(",").forEach{it -> it.removeSurrounding("\"")}
forEach doesn't return the value you generate in it, it's really just a replacement for a for loop that performs the given action. What you need here is map:
val splitCountries: List<String> = countries.split(",").map { it.removeSurrounding("\"") }
Also, a single parameter in a lambda is implicitly named it, you only have to name it explicitly if you wish to change that.

HTML::TreeBuilder::XPath findvalue returns concatenation of values

The findvalue function in HTML::TreeBuilder::XPath returns a concatenation of any values found by the xpath query.
Why does it do this, and how could a concatenation of the values be useful to anyone?
Why does it do this?
When you call findvalue, you're requesting a single scalar value. If there are multiple matches, they have to be combined into a single value somehow.
From the documentation for HTML::TreeBuilder::XPath:
findvalue ($path)
...If the path returns a NodeSet, $nodeset->xpath_to_literal is called automatically for you (and thus a Tree::XPathEngine::Literal is returned).
And from the documentation for Tree::XPathEngine::NodeSet:
xpath_to_literal()
Returns the concatenation of all the string-values of all the nodes in the list.
An alternative would be to return the Tree::XPathEngine::NodeSet object so the user could iterate through the results himself, but the findvalues method already returns a list.
How could a concatenation of the values be useful to anyone?
For example:
use strict;
use warnings 'all';
use 5.010;
use HTML::TreeBuilder::XPath;
my $content = do { local $/; <DATA> };
my $tree = HTML::TreeBuilder::XPath->new_from_content($content);
say $tree->findvalue('//p');
__DATA__
<p>HTML is just text.</p>
<p>It can still make sense without the markup.</p>
Output:
HTML is just text.It can still make sense without the markup.
Usually, though, it makes more sense to get a list of matches and iterate through them instead of doing dumb concatenation, so you should use findvalues (plural) if you could have multiple matches.
Use
( $tree->findvalues('//p') )[0] ;
instead.

What do empty square brackets after a variable name mean in Groovy?

I'm fairly new to groovy, looking at some existing code, and I see this:
def timestamp = event.timestamp[]
I don't understand what the empty square brackets are doing on this line. Note that the timestamp being def'd here should receive a long value.
In this code, event is defined somewhere else in our huge code base, so I'm not sure what it is. I thought it was a map, but when I wrote some separate test code using this notation on a map, the square brackets result in an empty value being assigned to timestamp. In the code above, however, the brackets are necessary to get correct (non-null) values.
Some quick Googling didn't help much (hard to search on "[]").
EDIT: Turns out event and event.timestamp are both zero.core.groovysupport.GCAccessor objects, and as the answer below says, the [] must be calling getAt() on these objects and returning a value (in this case, a long).
The square brackets will invoke the underlying getAt(Object) method of that object, so that line is probably invoking that one.
I made a small script:
class A {
def getAt(p) {
println "getAt: $p"
p
}
}
def a = new A()
b = a[]
println b.getClass()
And it returned the value passed as a parameter. In this case, an ArrayList. Maybe that timestamp object has some metaprogramming on it. What does def timestamp contains after running the code?
Also check your groovy version.
Empty list, found this. Somewhat related/possibly helpful question here.
Not at a computer, but that looks like it's calling the method event.timestamp and passing an empty list as a parameter.
The same as:
def timestamp = event.timestamp( [] )

Resources