1

This is my nested map, I want to iterate over each "myMap":

def myMaps = [
    "myMap1": [
      "prop1": 'sdfsdfdsf',
      "prop2": 'dsdfsdfs',
      "prop3": 'sdfsdfsdf'
    ],
    "myMap2": [
      "prop1": 'sdfsdfdsf',
      "prop2": 'dsdfsdfs',
      "prop3": 'sdfsdfsdf'
    ]
    "myMap3": [
      "prop1": 'sdfsdfdsf',
      "prop2": 'dsdfsdfs',
      "prop3": 'sdfsdfsdf'
    ]
    "myMap4": [
      "prop1": 'sdfsdfdsf',
      "prop2": 'dsdfsdfs',
      "prop3": 'sdfsdfsdf'
    ]
]

I tried this several ways but it's not iterating over the maps, it's still treating it like a single item:

myMaps.each() {
    println '========'
    it.dump()
}

for (item in myMaps) {
    println '========'
    println item.key
}

Edit

This was the only way I could manage to do this but I don't understand why. Is this also possible with a more traditional foreach style loop?

myMaps.each {
  key, value ->
    println key
    println value
}
halfer
  • 19,824
  • 17
  • 99
  • 186
red888
  • 27,709
  • 55
  • 204
  • 392
  • 1
    Not sure what the question is... `myMaps.each { it -> println "$it.key -> $it.value" }` works... is that not what you want? – tim_yates Jul 13 '21 at 15:35
  • I'm confused why this is the only way that works. This top rated question in this post says you can do it with a for loop, but it didn't work for me: https://stackoverflow.com/questions/10037374/loop-through-map-in-groovy – red888 Jul 13 '21 at 15:41
  • 1
    You can... this works the same `for (k in myMaps) { println "$k.key -> $k.value" }` – tim_yates Jul 13 '21 at 15:52
  • 1
    `k` is an entry, so if you want the key, you need to use `k.key` (and the same for value) – tim_yates Jul 13 '21 at 15:52
  • "I'm confused why this is the only way that works" - It isn't the only way. There are a lot of ways to iterate over a `Map`. Are you specifically wanting to know how to do it without using the `each` method for some reason? – Jeff Scott Brown Jul 13 '21 at 17:53

1 Answers1

1

How do I iterate over a nested map?

One way to do it is with the each(Closure) method:

def myMaps = [
        "myMap1": [
                "prop1": 'sdfsdfdsf',
                "prop2": 'dsdfsdfs',
                "prop3": 'sdfsdfsdf'
        ],
        "myMap2": [
                "prop1": 'sdfsdfdsf',
                "prop2": 'dsdfsdfs',
                "prop3": 'sdfsdfsdf'
        ],
        "myMap3": [
                "prop1": 'sdfsdfdsf',
                "prop2": 'dsdfsdfs',
                "prop3": 'sdfsdfsdf'
        ],
        "myMap4": [
                "prop1": 'sdfsdfdsf',
                "prop2": 'dsdfsdfs',
                "prop3": 'sdfsdfsdf'
        ]
]

myMaps.each { outerKey, outerValue ->
    println "${outerKey}:"
    outerValue.each { innerKey, innerValue ->
        println "\t${innerKey} -> ${innerValue}"
    }
}

Output:

myMap1:
    prop1 -> sdfsdfdsf
    prop2 -> dsdfsdfs
    prop3 -> sdfsdfsdf
myMap2:
    prop1 -> sdfsdfdsf
    prop2 -> dsdfsdfs
    prop3 -> sdfsdfsdf
myMap3:
    prop1 -> sdfsdfdsf
    prop2 -> dsdfsdfs
    prop3 -> sdfsdfsdf
myMap4:
    prop1 -> sdfsdfdsf
    prop2 -> dsdfsdfs
    prop3 -> sdfsdfsdf

EDIT:

The question was edited to add the following:

Is this also possible with a more traditional foreach style loop?

If you want to use a for loop, there are a number of ways to do that. One is shown here:

    for(Map.Entry outerEntry : myMaps) {
        println "${outerEntry.key}"
        for(Map.Entry innerEntry: outerEntry.value) {
            println "\t${innerEntry.key} -> ${innerEntry.value}"
        }
    }
Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47