Hernán Erasmo
Hernán Erasmo

Reputation: 371

Changing the values of a map nested in another map

Using HQL queries I've been able to generate the following map, where the keys represent the month number constant defined in java.util.Calendar, and every value is a map:

[
    0:[ client_a:[order1, order2, order3]],
    1:[ client_b:[order4], client_c:[order5, order6], client_d:[order7]],
    2:[ client_e:[order8, order9], client_f:[order10]]
]

order1, order2, ... are instances of a domain class called Order:

class Order {
    String description
    Date d
    int quantity
}

Now I've got that structure containing orders that belong to some specific year, but I don't really care about the Order object itself. I just want the sum of the quantities of all the orders of each month. So the structure should look something like this:

[
    0:[ client_a:[321]],
    1:[ client_b:[9808], client_c:[516], client_d:[20]],
    2:[ client_e:[22], client_f:[10065]]
]

I don't mind if the values are lists of one element or not lists at all. If this is possible, it would be fine anyway:

[
    0:[ client_a:321 ],
    1:[ client_b:9808, client_c:516, client_d:20 ],
    2:[ client_e:22, client_f:10065 ]
]

I know I have to apply something like .sum{it.quantity} to every list of orders to get the result I want, but I don't know how to iterate over them as they are nested within another map.

Thank you.

Upvotes: 2

Views: 447

Answers (2)

dmahapatro
dmahapatro

Reputation: 50245

def map = [
    0:[ client_a:[[q: 23], [q: 28], [q: 27]]],
    1:[ client_b:[[q: 50]], client_c:[[q: 100], [q: 58]], client_d:[[q: 90]]],
    2:[ client_e:[[q: 48], [q: 60]], client_f:[[q: 72]]]
]

map.collectEntries { k, v ->
    [ k, v.collectEntries { key, val ->
        [ key, val*.q.sum() ]
    } ]
}

you can also use val.sum { it.q } instead of val*.q.sum()

Upvotes: 2

Opal
Opal

Reputation: 84756

Here You go:

class Order {
    String description
    Date d
    int quantity
}

def orders = [
    0:[ client_a:[new Order(quantity:1), new Order(quantity:2), new Order(quantity:3)]],
    1:[ client_b:[new Order(quantity:4)], client_c:[new Order(quantity:5), new Order(quantity:6)], client_d:[new Order(quantity:7)]],
    2:[ client_e:[new Order(quantity:8), new Order(quantity:9)], client_f:[new Order(quantity:10)]]
]

def count = orders.collectEntries { k, v ->
    def nv = v.collectEntries { nk, nv -> 
        [(nk): nv*.quantity.sum()]
    }
    [(k):(nv)]
}

assert count == [0:[client_a:6], 1:[client_b:4, client_c:11, client_d:7],2:[client_e:17, client_f:10]]

Upvotes: 3

Related Questions