我需要合并到地图,同时执行一些计算,例如,下面的地图总是大小相同
CREATE TYPE UDT1 (
field1 text,
field2 int,
field3 text
);
CREATE TYPE UDT2 (
field1 boolean,
field2 float
);
CREATE TABLE cypher.table1 (
id int PRIMARY KEY,
list1 list<frozen<UDT1>>,
data text,
set1 set<frozen<UDT2>>
) WITH bloom_filter_fp_chance = 0.01
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
AND comment = ''
AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND crc_check_chance = 1.0
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99PERCENTILE';
我想要这张地图
def map1 = [
[name: 'Coord1', quota: 200],
[name: 'Coord2', quota: 300]
]
def map2 = [
[name: 'Coord1', copiesToDate: 270],
[name: 'Coord2', copiesToDate: 30]
]
现在我正在尝试使用此解决方案及其工作
def map3 = [
[name: 'Coord1', quota: 200, copiesToDate: 60, balance: 140],
[name: 'Coord2', quota: 300, copiesToDate: 30, balance: 270]
]
请你分享一个常规方法来完成这项任务。感谢
答案 0 :(得分:3)
我能提出的最流行的代码:
def map3 = [map1, map2].transpose()*.sum().each { m ->
m.balance = m.quota - m.copiesToDate
}
编辑:如Tim所述,只要两个输入列表(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,当您第一次看到它时可能需要一些努力。如果您有一个列表列表,您可以看到转置为将列表翻转到另一个方向&#34;。 在我们的案例中有两个列表:
[[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相关的所有内容都在第二个列表中。
*.
,我们会在每个地图列表上调用sum()
。 即:
[[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
属性添加到地图中,以便我们遍历现在的两个地图列表,并添加余额作为配额计算 - copiesToDate。 each
构造返回它正在处理的列表,这是我们分配给x的内容。 答案 1 :(得分:2)
另一个有趣的选择: - )
def result = (map1 + map2).groupBy { it.name }
.values()
*.sum()
.collect { it << ['balance': it.quota - it.copiesToDate] }
balance
答案 2 :(得分:1)
请勿两次致电find
。使用Map.plus()方法追加新条目。处理map2中缺少的名称。
def map3 = map1.collect {m1 ->
def m2 = map2.find {it.name == m1.name} ?: [copiesToDate: 0]
m1 + m2 + [balance: m1.quota - m2.copiesToDate]
}