【发布时间】:2016-07-15 11:58:36
【问题描述】:
我有一个序列对(键,值),比如
[("a", 1), ("a", 2), ("a", 111), ("b", 3), ("bb", 1), ("bb", -1), ...]
,将其转换为类似序列的最有效方法是什么
[("a", [1,2,111]), ("b", [3]), ("bb", [1,-1])]
或类似的?
该序列具有以下属性:非常大(>2Gb)
这使得 Seq.groupBy 真的无效且不正确,有没有其他方法可以做到?
P.S.:这个顺序:
[("a", 1), ("a", 2), ("a", 111), ("bb", 1), ("bb", -1), ("a", 5), ("a", 6), ...]
应该转换为
[("a", [1,2,111]), ("bb", [1,-1]), ("a", [5,6]), ...]
--
编辑#1:修正了不正确的样本
编辑 #2:序列很大,因此首选惰性(或最快)解决方案
【问题讨论】:
-
seq.groupby 怎么错了?
-
@JohnPalmer: groupBy 使用dictionary internally,我想这是 OP 想要避免的。他似乎在追求类似于
uniq的行为,其中只计算相邻的重复项。 -
@AntonSchwaighofer - groupby 可能不正确的原因有很多 - 我试图让 OP 说出适用于他的情况 -
-
@JohnPalmer groupBy 在这种情况下不正确,因为对于 [("a", 1), ("a", 2), ("a", 111), ("bb", 1 ), ("bb", -1), ("a", 5), ("a", 6), ...] 它将返回 [("a", [1,2,111, 5, 6]) , ("bb", [1,-1]), ...] 而不是 [("a", [1,2,111]), ("bb", [1,-1]), ("a" , [5,6]), ...]
-
@MarkSeemann 这个问题并不是真正的重复,因为它需要懒惰。此外,我们可以生成带有急切块的惰性序列。用
Some包裹输入序列,打上None;使用前一个键和一个累加器作为状态馈送到Seq.scan。最后以Seq.choose剥离状态。