Самый крутой код, который я мог придумать:
def map3 = [map1, map2].transpose()*.sum().each { m ->
m.balance = m.quota - m.copiesToDate
}
редактировать: как отметил Тим, этот код работает до тех пор, пока два входных списка (map1 и map2) имеют одинаковый размер и имеют карты в порядке. Если это не так, я бы порекомендовал ответ Тима, который обрабатывает эти случаи.
Вышеприведенное возвращает карту, как определено в вашем вопросе. Следующий код:
def list1 = [
[name: 'Coord1', quota: 200],
[name: 'Coord2', quota: 300]
]
def list2 = [
[name: 'Coord1', copiesToDate: 60],
[name: 'Coord2', copiesToDate: 30]
]
def x = [list1, list2].transpose()*.sum().each { m ->
m.balance = m.quota - m.copiesToDate
}
x.each {
println it
}
демонстрирует идею и печатает:
[name:Coord1, quota:200, copiesToDate:60, balance:140]
[name:Coord2, quota:300, copiesToDate:30, balance:270]
Я переименовал map1
и map2
в list1
и list2
, поскольку на самом деле это два списка, содержащие внутренние карты.
Код несколько лаконичен и может потребовать небольшого пояснения, если вы не привыкли к transpose
и отличным операциям распространения и отображения.
Пояснение:
[list1, list2]
- сначала мы создаем новый список, где два существующих списка являются элементами. Итак, теперь у нас есть список списков, в котором элементы внутренних списков являются картами.
.transpose()
— затем мы вызываем transpose для понимания которого может потребоваться некоторое усилие, когда вы видите его в первый раз. Если у вас есть список списков, транспонирование можно рассматривать как переворачивание списков «в другом направлении».
В нашем случае два списка:
[[name:Coord1, quota:200], [name:Coord2, quota:300]]
[[name:Coord1, copiesToDate:60], [name:Coord2, copiesToDate:30]]
стали:
[[name:Coord1, quota:200], [name:Coord1, copiesToDate:60]]
[[name:Coord2, quota:300], [name:Coord2, copiesToDate:30]]
т. е. после транспонирования все, что относится к Coord1, находится в первом списке, а все, что относится к Coord2, — во втором.
- Каждый из списков, которые у нас есть сейчас, представляет собой список карт. Но нам нужна только одна карта для Coord1 и одна карта для Coord2. Итак, для каждого из приведенных выше списков нам теперь нужно объединить или объединить содержащиеся карты в одну карту. Мы делаем это, используя тот факт, что в groovy map+map возвращает объединенную карту. Таким образом, с помощью оператора Groovy Spread
*.
мы вызываем sum()
для каждого списка. карт.
i.e.:
[[name:Coord1, quota:200], [name:Coord1, copiesToDate:60]].sum()
вычисляется в:
[name:Coord1, quota:200, copiesToDate:60]
и:
[[name:Coord2, quota:300], [name:Coord2, copiesToDate:30]].sum()
в:
[name:Coord2, quota:300, copiesToDate:30]
- наконец, мы хотим добавить свойство
balance
к картам, чтобы мы перебирали то, что теперь представляет собой список из двух карт, и добавляли баланс как вычисление квоты - copyToDate. Конструкция each
возвращает список, над которым она работает, и это то, что мы присваиваем x.
13.02.2017