Remove null and empty values using collect with string array [duplicate] - groovy

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(",")

Related

In Groovy - How to Iterate the versions in the list?

I am performing below task in jenkinsfile using groovy. where i have below variables
list C=[1.1,1.2,1.3]
String A=1.1
String B=1.3
if ("${A}" == "${B}") {
echo "No Action needed"
} else if ("${A}" != "${B}") {
then check in the variable list C and then iterate the list in sequential order.
}
Need Help in this condition. I am newbie in groovy.
When the A is != to B then it check the version from list C
Expected Output:-
1.1 == 1.3
then check in list C [1.1,1.2,1.3]
Iterate
1.2 ==1.3
print "still need iteration"
1.3 == 1.3
print " Matched"
I have Tried below code but its not doing iteration in for loop for If condition.
def C = ['1.1', '1.2', '1.3']
A=1.1
B=1.3
if ('${A}' == '${B}') {
println "equal"
}
else if ('${A}' != '${B}') {
println "not equal"
for (i = 0; i < C.size(); i++) {
println C[i]
if ('C[i]' == '${B}') {
println "equal"
}
}
}
there are several issues in your code
A,B are numeric and C is array of strings. to compare objects you need same type.
'C[i]' == '${B}' is incorrect because you are comparing literal string 'C[i]' to B converted to GString "1.3"
better to avoid this kind of comparison '${A}' == '${B}' - result could be tricky. better to use A == B
so, your code with changes
def C = ['1.1', '1.2', '1.3']
A='1.1'
B='1.3'
if (A == B) {
println "equal"
} else {
println "not equal"
for (i = 0; i < C.size(); i++) {
println C[i]
if (C[i] == B) {
println "equal"
}
}
}
result:
not equal
1.1
1.2
1.3
equal

Groovy: Compare float values and find out greater value

I have a float value and a list of float values where I want to compare the float value with list and find out the greater value than the float value and greater than the whole number of the float value with the list.
Eg:
cv = 1.5
av = [1.1,1.5,1.7,1.9,1.11,2.1,2.5]
Current code :
versions = av.findAll {
def isVersionGreater
it.indexed().any { i, v ->
if (cv[i] == v) return false
isVersionGreater = v > (cv[i] ?: 0)
return true
}
return isVersionGreater
}
versions.removeAll { it[0] > cv[0] }
versions.collect { it.join('.') }
which prints [1.7,1.9,1.11], but I don't want the value with 1, I want to compare and find out only [2.1,2.5] not the other values.
Note: I am collecting the variables av and cv as below
av = output2.tokenize().collect { it.tokenize('.').collect { it as int } }
cv = output.tokenize().collect { it.tokenize('.').collect { it as int } }.first()
Could someone help me to achieve this using groovy?
Use <= instead of >:
versions.removeAll { it[0] <= cv[0] }
print versions.collect { it.join('.') }
It means remove all from it where its first value is less or equal to first value of cv.
Output:
[2.1, 2.5]

Groovy iterating list variables

I am working on a script to collect field names (dialogPartyASelection_* && dialogPartyBSelection_*) and then compare the two values to see check if they match. The full list(selections)of fields is being broken down into 'groups' before comparison. I can break out certain parts (IE, comparing the two field values via iteration) and test successfully, however when bringing everything together the script doesn't seem to compare correctly. I may be approaching this/setting myself up to do this wrong, (have started to toy with creating a map, with party A as the key with party B as value).
Snippet of code:
// Test Variables
PartyBSelection_Propertieshamster = 'Accepted'
PartyBSelection_Propertieszembra = 'Agreed'
PartyBSelection_Propertiesdogs = 'Agreed'
PartyBSelection_Propertiescats = 'Decision taken'
PartyASelection_Propertieshamster = 'Accepted'
PartyASelection_Propertieszembra = 'Agreed'
PartyASelection_Propertiesdogs = 'Agreed'
PartyASelection_Propertiescats = 'Decision taken'
// example of selections(there are lots of entries for A/B party) = ['dialogPartyBSelection_Communication','dialogPartyASelection_Housing','dialogPartyASelection_Income','PartyASelection_Properties']
def selectedGroup = { s -> selections.findAll { it.contains s}} // for pulling groups of questions from list
def isAgreed = { a, b -> (a in ['Agreed', 'Decision taken','Accepted'] && b in ['Agreed', 'Decision taken','Accepted']) } // for comparing values
for(questions in selectedGroup("Properties")){
{k -> percentCompleteProperties += isAgreed("PartyASelection_${k}", "PartyBSelection_${k}")? 1 : 0}
println questions
println percentCompleteProperties
}
Current output:
PartyBSelection_Propertiescats
0
PartyBSelection_Propertieshamster
0
PartyBSelection_Propertiesdogs
0
PartyBSelection_Propertieshamster
0
PartyASelection_Propertiescats
0
PartyASelection_Propertieshamster
0
PartyASelection_Propertiesdogs
0
PartyASelection_Propertieshamster
0
This is sample code.
but i had changed test data etc.
please check whether this logic is correct for your case.
// Test Variables
def testVariables = [
'PartyBSelection_PropertiesAssets':'Accepted',
'PartyBSelection_PropertiesDebts': 'Agreed',
'PartyBSelection_PropertiesMoney': 'Agreed',
'PartyBSelection_PropertiesSpecialGoods':'Decision taken',
'PartyASelection_PropertiesAssets':'Accepted',
'PartyASelection_PropertiesDebts':'Agreed',
'PartyASelection_PropertiesMoney':'Agreed',
'PartyASelection_PropertiesSpecialGoods':'Decision taken'
]
List<String> selections= [
'PropertiesAssets',
'PropertiesDebts',
'PropertiesMoney',
'PropertiesSpecialGoods',
'PropertiesAssets',
'PropertiesDebts',
'PropertiesMoney',
'PropertiesSpecialGoods'
]
def selectedGroup = { s -> selections.findAll { it.contains s}}
List<String> okLabels = ['Agreed', 'Decision taken','Accepted']
def isAgreed = {a, b ->
(testVariables[a] in okLabels && testVariables[b] in okLabels)
}
List<Map<String, Integer>> result = selectedGroup("Properties").collect {String question ->
[(question) : isAgreed("PartyASelection_${question}", "PartyBSelection_${question}")? 1 : 0 ]
}
assert result == [
['PropertiesAssets':1],
['PropertiesDebts':1],
['PropertiesMoney':1],
['PropertiesSpecialGoods':1],
['PropertiesAssets':1],
['PropertiesDebts':1],
['PropertiesMoney':1],
['PropertiesSpecialGoods':1]
]
Other way
def r = [:]
def questionsCount = selectedGroup("Properties").size()
selectedGroup("Properties").eachWithIndex {String question, Integer i ->
println "question:${question}(${i+1}/${questionsCount})"
r.put(question,isAgreed("PartyASelection_${question}", "PartyBSelection_${question}")? 1 : 0 )
}
// This version includes all records in to the one map.
// Also, a record that is duplicated (as key) is overwritten.
r == [PropertiesAssets:1, PropertiesDebts:1, PropertiesMoney:1, PropertiesSpecialGoods:1]
then output:
question:PropertiesAssets(1/8)
question:PropertiesDebts(2/8)
question:PropertiesMoney(3/8)
question:PropertiesSpecialGoods(4/8)
question:PropertiesAssets(5/8)
question:PropertiesDebts(6/8)
question:PropertiesMoney(7/8)
question:PropertiesSpecialGoods(8/8)

Update map using findAll and each in groovy

I would like to update values in map in Groovy filling certain criteria. Here is my code:
def m = [:]
m['a'] = 1
m['b'] = 2
m['d'] = 3
m.findAll { it.value > 1}.each {
it.value = 4
}
println m
But the result is following:
[a:1, b:2, d:3]
Is there any way to do it using both findAll and each? Or I must use
m.each {if (it.value>1) it.value=4}
The root cause is findAll returns a new Map instance.
So you could try:
newMap = m.findAll { it.value > 1}.each {
it.value = 4
}
println m //No change
println newMap //This is what you need!
output is
[a:1, b:2, d:3]
[b:4, d:4]
In each case, the values you are iterating with the each are map entries with a pointer to key and value. When you set it.value you are not replacing what is in the map. You are only updating the pointer in the map entry. To actually set the value, you will need to do the following:
m.findAll { it.value > 1 }.each { m[it.key] = 4 }

Difference of two maps in groovy using collectEntries

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

Resources