Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing elements of a map of maps using a string in Groovy

Tags:

map

groovy

Given I have a map like:

def myMap = [ b : [ c:"X" ] ]

And a string

def key = 'b.c'

I'd like to see my options for using the key to get to the value 'X'.

I have come up with two ways of achieving this myself, but I am not very happy with these solutions:

 1) Eval.me("theMap", myMap, "theMap.$key")
 2) mayMap."$key.split('\\.')[0]"."$key.split('\\.')[1]"

Anyone has a better way of doing this in Groovy?

like image 548
Armin Avatar asked Jul 02 '13 23:07

Armin


People also ask

How do I add a map to groovy map?

The easiest way to merge two maps in Groovy is to use + operator. This method is straightforward - it creates a new map from the left-hand-side and right-hand-side maps.

How do I use Groovy maps?

Maps are generally used for storing key-value pairs in programming languages. You have two options to declare a map in groovy. First option is, define an empty map and put key-value pairs after. Second option is declaring map with default values.

How do I sort a map in groovy?

Maps don't have an order for the elements, but we may want to sort the entries in the map. Since Groovy 1.7. 2 we can use the sort() method which uses the natural ordering of the keys to sort the entries. Or we can pass a Comparator to the sort() method to define our own sorting algorithm for the keys.

What is groovy Hashmap?

A hashmap maps a key to a value, but you are trying to map a key to two values. To do this, create a hashmap, where the key is your ID and the value is another hashmap, mapping the string "firstname" to "Jack" and the string "lastname" to "Sparrow" and so on for all <person> elements.


2 Answers

A convenient way is to use ConfigObject which implements Map.

def myMap = [b:[c:'X', d: 'Y'], a:[n:[m:[x:'Y']]]] as ConfigObject
def props = myMap.toProperties()

assert props['b.c'] == 'X'
assert props.'b.c' == 'X'
assert props.'a.n.m.x' == 'Y'

Pros:

  • No more splitting.
  • No more evaluating.
like image 62
dmahapatro Avatar answered Sep 18 '22 11:09

dmahapatro


IMHO its not the ConfigObject, that does the trick, its the Properties (from ConfigObject.toProperties()). Look & try:

def props = new ConfigSlurper().parse("""
b {
 c = 'X'
 d = 'Y'
}
a {
 n {
   m {
     x:'Y'
   }
 }
}""")

assert props['b.c'] == 'X'
assert props.'b.c' == 'X'
assert props.'a.n.m.x' == 'Y'
'passed'

Assertion failed:

assert props['b.c'] == 'X'
       |    |       |
       |    [:]     false
       [b:[c:X, d:Y], a:[n:[m:[:]]], b.c:[:]]

    at ConsoleScript7.run(ConsoleScript7:14)

and I really wish, the ConfigObject could be indexed with such combined keys like above

like image 45
Werner Avatar answered Sep 16 '22 11:09

Werner