Scala 的 Map.unzip 返回的原因(可迭代,可迭代)

发布于 2024-10-28 19:59:42 字数 893 浏览 2 评论 0原文

有一天,我想知道为什么 scala.collection.Map 将其 unzip 方法定义为

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))

结果。虽然我可以想象这背后与存储相关的原因(例如,考虑 HashMap),但我想知道你们对这种行为有何看法。对于 Map.unzip 方法的用户来说,这些项目可能会以相同的配对顺序返回(我敢打赌这可能几乎总是如此),但因为不能保证这可能会反过来产生难以发现的错误图书馆用户的代码。

也许这种行为应该在随附的 scaladoc 中更明确地表达?

编辑:请注意,我并不是将地图称为有序集合。我只对解压后的“匹配”序列感兴趣,即因为

val (keys, values) = someMap.unzip

它适用于所有我(keys(i), value(i)) 是原始映射的元素。

the other day I was wondering why scala.collection.Map defines its unzip method as

def unzip [A1, A2] (implicit asPair: ((A, B)) ⇒ (A1, A2)): (Iterable[A1], Iterable[A2])

Since the method returns "only" a pair of Iterable instead of a pair of Seq it is not guaranteed that the key/value pairs in the original map occur at matching indices in the returned sequences since Iterable doesn't guarantee the order of traversal. So if I had a

Map((1,A), (2,B))

, then after calling

Map((1,A), (2,B)) unzip

I might end up with

... = (List(1, 2),List(A, B))

just as well as with

... = (List(2, 1),List(B, A))

While I can imagine storage-related reasons behind this (think of HashMaps, for example) I wonder what you guys think about this behavior. It might appear to users of the Map.unzip method that the items were returned in the same pair order (and I bet this is probably almost always the case) yet since there's no guarantee this might in turn yield hard-to-find bugs in the library user's code.

Maybe that behavior should be expressed more explicitly in the accompanying scaladoc?

EDIT: Please note that I'm not referring to maps as ordered collections. I'm only interested in "matching" sequences after unzip, i.e. for

val (keys, values) = someMap.unzip

it holds for all i that (keys(i), values(i)) is an element of the original mapping.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

漫漫岁月 2024-11-04 19:59:42

如果你展开unzip的描述,你会得到答案:

definition classes: GenericTraversableTemplate

换句话说,它并没有专门用于Map

不过,你的论点是合理的,我敢说,如果你用你的推理开一张增强票,你可能会如愿以偿。特别是如果您继续制作补丁——如果不出意外,至少您会在这样做时学到更多关于 Scala 集合的知识。

If you expand unzip's description, you'll get the answer:

definition classes: GenericTraversableTemplate

In other words, it didn't get specialized for Map.

Your argument is sound, though, and I daresay you might get your wishes if you open an enhancement ticket with your reasoning. Specially if you go ahead an produce a patch as well -- if nothing else, at least you'll learn a lot more about Scala collections in doing so.

岛徒 2024-11-04 19:59:42

其实你举的例子是不会出现的。 Map 将始终以成对的方式解压缩。您关于 Iterable 不保证排序的说法并不完全正确。更准确地说,任何给定的 Iterable 不必保证顺序,但这取决于实现。在 Map.unzip 的情况下,不能保证对的顺序,但对中的项目不会改变它们的匹配方式——匹配是 的基本属性地图。您可以阅读 源代码GenericTraversableTemplate 来验证情况是否如此。

Actually, the examples you gave will not occur. The Map will always be unzipped in a pair-wise fashion. Your statement that Iterable does not guarantee the ordering, is not entirely true. It is more accurate to say that any given Iterable does not have to guarantee the ordering, but this is dependent on implementation. In the case of Map.unzip, the ordering of pairs is not guaranteed, but items in the pairs will not change they way they are matched up -- that matching is a fundamental property of the Map. You can read the source to GenericTraversableTemplate to verify this is the case.

南街女流氓 2024-11-04 19:59:42

一般来说,地图没有自然序列:它们是无序的集合。您的键碰巧具有自然顺序这一事实并不会改变一般情况。

(但是我无法解释为什么 Map 有一个 zipWithIndex 方法。这为我的观点提供了一个反驳。我猜它的存在是为了与其他集合保持一致,尽管它提供了索引,不保证它们在后续调用中相同。)

Maps, generally, do not have a natural sequence: they are unordered collections. The fact your keys happen to have a natural order does not change the general case.

(However I am at a loss to explain why Map has a zipWithIndex method. This provides a counter-argument to my point. I guess it is there for consistency with other collections and that, although it provides indices, they are not guaranteed to be the same on subsequent calls.)

浪菊怪哟 2024-11-04 19:59:42

如果您使用 LinkedHashMap 或 LinkedHashSet,迭代器应该按原始插入顺序返回对。其他 HashMap,是的,你无法控制。保留原始插入顺序在 UI 上下文中非常有用,例如,它允许您在 Web 应用程序中的任何列上重新使用表,而无需更改类型。

If you use a LinkedHashMap or LinkedHashSet the iterators are supposed to return the pairs in the original order of insertion. Other HashMaps, yeah, you have no control. Retaining the original order of insertion is quite useful in UI contexts, it allows you to resort tables on any column in a Web application without changing types, for instance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文