我有一张带有两个键(customer
和price
)的地图,如下图所示:
[
customer: ['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'],
price: [15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]
customer
和price
值通过它们的索引位置进行映射,即customer
列表中的名字与第一个价格,依此类推。
示例
Cliton price is 15000.0
Cliton price 27000.0
Mark price 28000.0
Antony price 56000.0
Clinton price 21000.0
Mark price 61000.0
我想总结按名称分组的价格。预期输出:
Clinton price 63000
Mark price 89000
Antony price 56000
在Groovy中是否有任何内置函数可以实现此目的,还是我需要通过编写自己的函数来迭代映射并求和值?
答案 0 :(得分:3)
您可以从两个列表上的转置开始,以获取客户和价格的元组。从那里基本上像其他答案一样(按客户分组,与客户建立地图并汇总价格)。例如:
def data = [
customer:['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'],
price:[15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]
println(
[data.customer, data.price].transpose().groupBy{ c, p -> c }.collectEntries{ c, ps -> [c, ps*.last().sum() ] }
)
// => [Clinton:63000.0, Mark:89000.0, Antony:56000.0]
答案 1 :(得分:1)
在这样的问题中,我们应该始终计划将每个条目作为一个单独的对象放在列表中,以使其在列表中直观且将来易于操作。
在这种情况下,自然可以得到相同的结果
android:digits="abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ !@#$%^*?"
答案 2 :(得分:0)
followint创建price
聚合的customer
映射:
def vals = (0..(-1+map.customer.size()))
.collect{['name':map.customer[it], 'price': map.price[it]]}
.groupBy{it['name']}
.collectEntries{[(it.key): it.value.collect{it['price']}.sum()]}
结果是:
[Clinton:63000.0, Mark:89000.0, Antony:56000.0]
从本质上讲,这是一次迭代,使用从0
到map.customer.size() - 1
的一系列数字,然后是带有值总和的分组依据。
答案 3 :(得分:0)
此版本源自@cfrick的答案,是求和的替代方法。使用具有默认值的地图并不是“功能性” /声明性的,但是恕我直言,可以说以后更容易查看代码(即维护):
给出:
def map = [
customer: ['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'],
price: [15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]
方法:
def getSumMap = { data ->
def result = [:].withDefault { c -> 0.0 }
[data.customer, data.price].transpose().each { c, p -> result[c] += p }
result
}
assert 63000.0 == getSumMap(map)['Clinton']
assert 89000.0 == getSumMap(map)['Mark']
assert 56000.0 == getSumMap(map)['Antony']