How can I access the original map after wrapping it with ObservableMap? - groovy

I've created a map and then wrapped it as an ObservableMap. Later on, I try to access the original, unwrapped map, but I can't seem to access it. It seems to come back null.
private def _swarms = [:]
private def swarms = new ObservableMap(_swarms)
...
def orig = swarms.content // returns null
orig = swarms.mapDelegate // returns null
I don't see anything else at http://groovy.codehaus.org/api/groovy/util/ObservableMap.html that looks promising.

We cannot refer the property as a field in case of a Map interface. It will try to look for a key with that name and would return null if key<->value pair is absent. Try this instead:
def _swarms = [ a : 1 ]
def swarms = new ObservableMap( _swarms )
assert swarms.getContent() == [ a : 1 ]
assert swarms.getMapDelegate() == [ a : 1 ]
// Similar anomaly
assert !swarms.class
assert swarms.getClass().simpleName == "ObservableMap"
Similarly, you cannot use .class on Map. Instead getClass() has to be used.

Related

Groovy remove null elements from a map

I am getting a map in my method from another server and I have some null values, I wanted to remove those ones, because I am struggling with those values in the following process:
My map looks something like:
I had done the next code, but without satisfactory results:
map.values().removeAll(Collections.singleton(null))
Any ideas?
Thanks
Edit
The Groovy way, is to filter the entries you want:
def map = [a:42, b:null]
def cleanMap = map.findAll{ it.value!=null }
println cleanMap
// => [a:42]
Previous answer:
Seems to work with Jdk8/Groovy 2.5, but not for OP
To remove all elements with a value with null, remove on the map directly:
def map = [a:42, b:null]
map.removeAll{ it.value == null }
println map
// => [a:42]

Retrieve value in map by key in Groovy

def text= '''<Rollback> <Kits>
<Kit ServerName='ust1twastool01a'>
<Backup>2016-10-18_20_34-46-_server-21.000.409_client-21.000.407.zip</Backup>
<Backup>2016-10-18_21_57-33-_server-21.000.409_client-21.000.407.zip</Backup>
<Backup>2016-10-19_02_40-03-_server-21.000.413_client-21.000.407.zip</Backup>
<Backup>2016-10-19_13_58-36-_server-21.000.413_client-21.000.407.zip</Backup>
<Backup>2016-10-20_03_14-34-_server-21.000.413_client-21.000.407.zip</Backup>
</Kit>
<Kit ServerName='another_server'>
<Backup>123123.zip</Backup>
<Backup>321321.zip</Backup>
</Kit>
</Kits></Rollback>'''
def xml = new XmlSlurper().parseText(text)
def map = [:]
i = 0
xml.Kits.Kit.each{node->
def list = []
node.Backup.each{kit->
list.add(kit)
}
map.put(node.#ServerName, list)
}
print map // print map with all keys and values
// Somehow, it's not working ...
print map['ust1twastool01a']
def map2 = ['1':["abc","123"], '2':["bcd", "456"]]
print map2['1']
​
I have been annoyed by the above code for almost the day. I don't understand why I can't get value by map['ust1twastool01a'].
I attached a screenshot from a console, it shows that map is not empty but just can't get its value by key. map2 is just control group as it has the similar structure to map string as key and list as value
Use as below:
map.put(node.#ServerName.text(), list)
On a side note, I believe you can simplify the code to just:
def xml = new XmlSlurper().parseText(text)
def map = xml.Kits.Kit.collectEntries { node ->
[ node.#ServerName.text(), node.Backup.collect() ]
}

Is there a functional programming way to retrieve the first element of a collection?

The list can be empty. I would like to do :
def value = "";
def list = getList()
if (!list.isEmpty()){
value = list.first().foo
}
for instance I have found this way :
assert ( [].find()?.foo?:"empty" ) == "empty"
assert ([[foo:"notEmpty1"], [foo:"notEmpty2"]].find()?.foo?:"empty") == "notEmpty1"
Is there a better way ?
Thanks! :)
EDIT:
I got great answer by using [0]
assert ( [][0]?.foo?:"empty" ) == "empty"
assert ([[foo:"notEmpty1"], [foo:"notEmpty2"]][0]?.foo?:"empty") == "notEmpty1"
If it is a List just try
if (!list?.isEmpty()){
list.get(0);
}
If the list element cannot be null you don't need the ?
If it is a Collection there are several forms to retrieve it. Take a look at this post
Java: Get first item from a collection
I got an answer from tweeter. The statements :
def value = "";
def list = getList()
if (!list.isEmpty()){
value = list.first().foo
}
Can be write :
def value = list[0]?.foo?:""
find may be use if the list can contain null values

Finding a value of a list

I have two lists
def flagList = SystemFlag.list()
this contains the domain objects of one table
I have another list which I create using a query. One of the parameter in the object of this list is contained in the flagList. How can I find if an id of FlagList is present in the second list?
I can do it in plain java but I need to use Groovy for this.
If I understood you correctly you have this situation:
def listeOne = [1,2,3,4,5]
def listTwo = [2,5,1]
You want to see if '2' of 'listTwo' is in 'listOne'.
Find a specific value:
def found = 2 in listTwo //returns a boolean of the interger 2 is in listTwo
Search for common value of both lists:
def intersectionsList = listOne.intersect(listTwo) //gives you a list of value that are in BORTH list
You can also iterate like this:
listTwo.each { value ->
if(value in listOne) println value //or do something lese
}
Alternatively:
listTwo.each { value ->
listOne.find {value}?.toString() //you can perform an action on the object found in listOne. using '?.' will make sure no nullpointer will be thrown if there is no result.
}
I found it using
def it = itemtofindsomehow
list.findIndexof { iterator ->
iterator.domain.id == it.id
}

Determining an end node from file parsed with XmlParser

I have a method which needs to search an xml file which was parsed using XmlParser for an element by name and return it only if that element is an end node. For example:
class xmlTest extends GroovyTestCase {
def void test(){
def xmlBody = """
<rootElement>
<elementWithOneChild>
<endElement>Here is the end</endElement>
</elementWithOneChild>
<elementWithManyChildren>
<one>1</one>
<two>1</two>
<three>1</three>
</elementWithManyChildren>
</rootElement>"""
def parsedBody = new XmlParser().parseText(xmlBody)
def search1 = parsedBody.depthFirst().grep({it.name() == "elementWithOneChild"})
println search1[0].children().size()
def search2 = parsedBody.depthFirst().grep({it.name() == "endElement"})
println search2[0].children().size()
def search3 = parsedBody.depthFirst().grep({it.name() == "elementWithManyChildren"})
println search3[0].children().size()
}
}
My attempt to use Node.children().size() works except for the 1 to 1 case where an element contains one child element. In this case, search1.children().size() and search2.children().size() both return 1. Although, the size for elementWithManyChildren is 3. I am looking for some way to be able to tell an end node apart from an element with one child.
One way I have found to work is:
try{
search1[0].children().iterator().next().name()
}catch(e){
//If the next node does not have a name, it is an end node
}
But that solution just seems like a poor one.
might waste a couple of cycles but this should allow you to find terminal nodes
assert search1[0].'**'.size() == 2
assert search2[0].'**'.size() == 1
assert search3[0].'**'.size() == 4

Resources