In Groovy, is there an elegant ( and clear ) way to check multiple objects for null ..example
def a = null
def b = null
def c = null
def d = null
// Is there a simpler ( more elegant ) version of this line of code
if ( a== null || b== null || c == null || d == null ) {
print "Null detected"
}
In Groovy, is there an elegant ( and clear ) way to check multiple objects for null
It may depend on your preference and what you find to be elegant, but the code you show there is idiomatic.
Related
I have a version like below and I want to add zero (0) in versionB after 2 decimal. How can I achieve this in groovy?
versionA=1.12.14
versionB=1.11
Expected OutPut:-
versionA=1.12.14
VersionB=1.11.0
Solution
The term you are are looking for is Semantic Versioning ( semver ). This is not the prettiest solution but it will work
//def semver = "1"
def semver = "1.13"
def split = semver.split("\\.");
if(split.size() == 1) {
semver+=".0.0"
} else if(split.size()==2) {
semver+=".0"
}
println semver
In your example you have the variables typed as numbers but they must be strings
A generic variant for version strings of variable lengths:
String getFormattedVersion( String raw, int maxPositions = 3 ){
def parts = raw.split( /\./ )
(0..<maxPositions).collect{ it < parts.size() ? parts[ it ] : '0' }.join '.'
}
assert '1.2.3' == getFormattedVersion( '1.2.3' )
assert '1.2.0' == getFormattedVersion( '1.2' )
assert '1.0.0' == getFormattedVersion( '1' )
assert '1.2.3.0.0' == getFormattedVersion( '1.2.3', 5 )
This question already has answers here:
Collection using join method on empty values
(2 answers)
Closed 7 years ago.
I've got a simple form that I'm trying to retrieve the values from. Except I want to remove the null or empty values from the collection. An example output that I'm getting is:
joey:admin:null::155:null
You can see values are coming through as null and one of the values is empty (the one with the two colons). What am I doing wrong I thought if I checked the size and the null check it wouldn't come through? Any ideas what I'm doing wrong?
String generateValues() {
return request.requestParameterMap
.findAll { key, value -> !(key in ["honeypot", "confirm"]) }
.collect { k, v -> if(v != null && v.size() > 0) v[0]
}.join(",")
}
You didn't check results of .collect. Also this closure will return nulls for empty keys (no else section).
Try this:
return request.requestParameterMap
.findAll { key, value -> !(key in ["honeypot", "confirm"]) }
.collect { k, v -> if(v != null && v.size() > 0) v[0] }
.findAll { x -> x != null && x.length() > 0 }
}.join(",")
or use .findResults instead of .collect:
return request.requestParameterMap
.findAll { key, value -> !(key in ["honeypot", "confirm"]) }
.findResults { k, v -> v?.size() > 0 && v[0]?.length() > 0 ? v[0] : null }
}.join(",")
I have a problem to get last two digit from a string.
example :
String texter = "5793231309"
how to get '09' ?
so when Iprintln "texter : "+texter.
It will be Groovy<<09
I try split but it not successful ?
Use this to split your first String:
static main(args) {
String texter = "5793231309"
String texter2 = texter[-2..-1]
println(texter2)
}
Here's a one liner that's also a safe alternative:
assert "5793231309".reverse().take(2).reverse() == "09"
In groovy you can substring via negative indices.
String last2 = texter[-2..-1] // Last 2 symbols
Its an analogue of substring, and it uses Ranges.
http://groovy.codehaus.org/Collections see 'Slicing with the subscript operator'
Inspired by tim_yates:
It may be safer to use some function, to extract last n characters, as tim suggested. But I think his solution, with regexp is a big overhead, and may be hard to understand by novices.
There is an easier and faster way to do this, using size() check, and then range substring:
def lastN(String input, int n){
return n > input?.size() ? null : n ? input[-n..-1] : ''
}
assert lastN("Hello", 2) == 'lo'
assert lastN("Hello", 3) == 'llo'
assert lastN("Hello", 0) == ''
assert lastN("Hello", 13) == null
assert lastN(null, 3) == null
Be careful though, if your unit is less than 2 characters long, s[ -2..-1 ] will fail.
Might be better to do:
String lastN( String input, int n ) {
input == null ?
null :
( input =~ /^.+(\S{$n})$/ ).with { m -> m.matches() ?
m[ 0 ][ 1 ] :
null }
}
assert lastN( "5793231309", 2 ) == '09'
assert lastN( "5793231309", 3 ) == '309'
assert lastN( "5793231309", 0 ) == ''
assert lastN( '', 2 ) == null
assert lastN( null, 2 ) == null
Or:
String lastN( String input, int n ) {
if( input == null || input.length() < n ) null
else if( n == 0 ) ''
else input[ -n..-1 ]
}
assert lastN( "5793231309", 2 ) == '09'
assert lastN( "5793231309", 3 ) == '309'
assert lastN( "5793231309", 0 ) == ''
assert lastN( '', 2 ) == null
assert lastN( null, 2 ) == null
The most readable solution is probably just to drop() all but the last two characters:
def texter = "5793231309"
println texter.drop(texter.size() - 2) //result: "09"
Or as a reusable closure:
def lastTwo = { it.drop(it.size() - 2) }
println lastTwo("ABC") //result: "BC"
println lastTwo("AB") //result: "AB"
println lastTwo("A") //result: "A" (no exception thrown)
println lastTwo("") //result: "" (no exception thrown)
Fiddle with the code:
https://groovyconsole.appspot.com/script/5768158526832640
More examples of Groovy goodness:
http://mrhaki.blogspot.com/2011/09/groovy-goodness-take-and-drop-items.html
Another safe alternative using size() and substring() methods:
s?.size() < 2 ? s : s.substring(s.size() - 2)
Note the above takes care of nulls and strings that are less than two characters long.
In Java use
String texter = "5793231309";
String val=texter.substring(texter.length()-2,texter.length());
System.out.println("val-->"+val);
In Groovy you don’t need the above stuff just,
String value= texter[-2..-1]
I am trying to find the difference between values in two maps
#Test
void testCollecEntries() {
def mapOne= ["A":900,"B":2000,"C":1500]
def maptwo = ["A":1000,"D":1500,"B":1500]
def balanceMap = maptwo.collectEntries { key, value-> [key:value-mapOne[key]] }
println balanceMap
}
I am trying to find the difference of values from maptwo with that of the values from mapOne. If the entry doesn't exist i need to ignore. This gives me a null pointer exception.
Appreciate any help.
It will throw NPE because you are looking for key "D" in mapOne which is not available.
You can avoid that by a null safe operation and default value to 0.
def one= [A:900, B:2000, C:1500]
def two = [A:1000, D:1500, B:1500]
def result = two.collectEntries{k,v -> [k, (v - (one[k]?:0))]}
println result
//Print
[A:100, D:1500, B:-500]
In case, you want to consider the common keys then use:
def result = two.collectEntries{k,v -> one[k] ? [k, (v - one[k])] : [:]}
//or
//def result = two.collectEntries{k,v -> (k in one.keySet()) ? [k, (v - one[k])] : [:]}
//Print
[A:100, B:-500]
You could look at this good example: http://groovyconsole.appspot.com/script/364002
I have this code:
def input1 = ['a','b','e','r','t']
input2 = ['v','n','m','y']
ans = []
def common(def element,def i) {
if (element == input2[i]) {
ans << element
return
} else {
common(element,++i)
}
}
for (i=0;i<input1.size();i++) {
common(input1[i],0)
}
which is generating Stack Overflow error. Why is this happening?
Edit:
I'm trying to create my own way of finding common element between two lists.
You never check if i is greater than the length of input2, and in Groovy, getting beyond the length of a List returns null
So on the first element, it will keep looping round
if (element == input2[i]) {
for ever-increasing values of i, calling the common function every time, as it never matches a
Guessing at what you are trying to do, this can all be re-written as:
def input1 = ['a','b','e','r','t']
def input2 = ['v','n','m','y']
def ans = input1.intersect( input2 )
But it's hard to be sure what you want, and you dont explicitly say.
Edit
One method of deep recursion that avoids Stack Overflows is to use Groovy's trampoline method.
def common
common = { Object element, Collection list ->
if( list.size() == 0 ) { // element not found. Return null
null
}
else if( list.head() == element ) { // element found. Return it
element
}
else {
common.trampoline( element, list.tail() ) // Trampoline down the list and check again
}
}
common = common.trampoline()
def elements = ['a','b','e','v','r','t'].collect { // For each element in this list
common( it, ['v','n','m','y'] ) // Find if it's in our other list
}.findAll() // And remove the nulls
assert elements == [ 'v' ]
But I'd still use intersect in this case, the above is just to show one of Groovy's ways you can avoid too-deep recursion...
The problem is that your code doesn't stop when reaches the end of array input2. If element is not in input2 then it will keep making recursive calls common(element,++i) forever which results in stack overflow error.