如何基于两个键求和地图值?

时间:2018-08-17 22:29:20

标签: groovy

我有一张带有两个键(customerprice)的地图,如下图所示:

[
    customer: ['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'], 
    price: [15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]

customerprice值通过它们的索引位置进行映射,即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中是否有任何内置函数可以实现此目的,还是我需要通过编写自己的函数来迭代映射并求和值?

4 个答案:

答案 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]

从本质上讲,这是一次迭代,使用从0map.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']