前几天,我想知道为什么scala.collection.Map将其解压缩方法定义为
def unzip [A1, A2] (implicit asPair: ((A, B)) ⇒ (A1, A2)): (Iterable[A1], Iterable[A2])由于该方法只返回一对Iterable而不是一对Seq,因此不能保证原始映射中的键/值对发生在返回序列中的匹配索引处,因为Iterable不能保证遍历的顺序。所以如果我有一个
Map((1,A), (2,B)),然后在打电话之后
Map((1,A), (2,B)) unzip我可能会以
... = (List(1, 2),List(A, B))就像和
... = (List(2, 1),List(B, A))虽然我可以想象这种行为背后与存储相关的原因(比如HashMaps ),但我想知道你们对这种行为有什么看法。在Map.unzip方法的用户看来,这些条目似乎是以相同的对顺序返回的(我敢打赌,情况几乎总是如此),但由于无法保证这反过来又会在库用户的代码中产生难以找到的bug。
也许这种行为应该更明确地表达在附带的scaladoc中?
编辑:请注意,我不是指地图是订购的集合。--我只对解压缩后的“匹配”序列感兴趣,即
val (keys, values) = someMap.unzip对于所有的i,它都认为(key(I),value(I))是原始映射的一个元素。
发布于 2011-03-31 15:41:26
实际上,你给出的例子不会发生。Map将始终以一对一的方式解压。您关于Iterable不能保证排序的说法并不完全正确。更准确的说法是,任何给定的Iterable都不必保证排序,但这取决于实现。在Map.unzip的情况下,不保证对的排序,但是对中的项不会改变它们的匹配方式--匹配是Map的一个基本属性。您可以将来源读入GenericTraversableTemplate以验证情况是否属实。
发布于 2011-03-31 15:15:21
如果你扩展unzip的描述,你就会得到答案:
definition classes: GenericTraversableTemplate换句话说,它没有专门用于Map。
不过,你的论点是合理的,我敢说,如果你用你的推理打开一张增强票,你可能会得到你的愿望。特别是,如果您继续生产一个修补程序--如果没有其他的话,那么至少在这样做的过程中,您将了解更多Scala集合。
发布于 2011-03-31 14:53:41
一般来说,地图没有自然序列:它们是无序的集合。事实上,你的钥匙碰巧有一个自然的顺序并没有改变一般情况。
(然而,我无法解释为什么Map有一个zipWithIndex方法。这为我的观点提供了一个反驳的理由。我想它是为了与其他集合的一致性而存在的,虽然它提供了索引,但在随后的调用中它们并不一定是相同的。)
https://stackoverflow.com/questions/5501753
复制相似问题