这 2 个 Ruby 枚举器之间的区别:[1,2,3].map 与 [1,2,3].group_by

Posted

技术标签:

【中文标题】这 2 个 Ruby 枚举器之间的区别:[1,2,3].map 与 [1,2,3].group_by【英文标题】:Differences between these 2 Ruby enumerators: [1,2,3].map vs. [1,2,3].group_by 【发布时间】:2014-07-13 13:41:33 【问题描述】:

在 Ruby 中,这两个枚举器在功能上有区别吗?

irb> enum_map = [1,2,3].map
=> #<Enumerator: [1, 2, 3]:map> # ends with "map>"

irb> enum_group_by = [1,2,3].group_by
=> #<Enumerator: [1, 2, 3]:group_by> # ends with "group_by>"

irb> enum_map.methods == enum_group_by.methods
=> true # they have the same methods

#&lt;Enumerator: [1, 2, 3]:map&gt; 可以做什么&lt;Enumerator: [1, 2, 3]:group_by&gt; 不能做,反之亦然?

谢谢!

【问题讨论】:

后一个,会给你一个Hash,如果你通过一个块,总是。但事实并非如此,使用前者,它总是会给你一个Array 还有enum_map.methods == enum_select.methods... 【参考方案1】:

来自group_by的文档:

按块的结果对集合进行分组。返回一个哈希,其中 键是块的评估结果,值是数组 集合中与键对应的元素的数量。

如果没有给出块,则返回枚举器。

(1..6).group_by  |i| i%3    #=> 0=>[3, 6], 1=>[1, 4], 2=>[2, 5]

来自map的文档:

返回一个新数组,其中包含每次运行块的结果 枚举中的元素。

如果没有给出块,则返回一个枚举器。

(1..4).map  |i| i*i       #=> [1, 4, 9, 16]
(1..4).collect  "cat"     #=> ["cat", "cat", "cat", "cat"]

如您所见,每个人都做不同的事情,用于不同的目的。得出两个 API 相同的结论是因为它们公开了相同的接口,这似乎错过了面向对象编程的全部目的 - 应该不同的服务公开相同的接口以启用 polymorphism。

【讨论】:

谢谢先生。我应该更具体。今天早些时候,我注意到[1,2,3].group_by(没有块)返回一个枚举器。然后我注意到[1,2,3].map(没有块)也返回一个枚举器。也许更好的问题是这个 => 我可以用[1,2,3].enum_for(:map) 返回的枚举器做什么,而我不能用[1,2,3].to_enum 返回的枚举器来做。 @amorphid - 你看过文档吗:ruby-doc.org/core-2.1.1/Enumerator.html? @amorphid 期望一个类的不同实例是相等的,这是一个根本性的错误。同样比较 enum_map.methods == enum_group_by.methods 只比较对象方法 names 而不是它们的实现甚至代码。【参考方案2】:

他们的工作有所不同,但从根本上说,他们都属于同一类:Enumerator

使用它们时,枚举器发出的值会有所不同,但它们的接口是相同的。

同一类的两个对象通常具有相同的方法。可以使用其他方法来扩充实例,但通常不会这样做。

【讨论】:

以上是关于这 2 个 Ruby 枚举器之间的区别:[1,2,3].map 与 [1,2,3].group_by的主要内容,如果未能解决你的问题,请参考以下文章

Ruby - 优雅地比较两个枚举器

ruby 创建一个接收N个枚举器的枚举器然后排序

差图,并且每个[重复]之间

没有循环迭代器的枚举

ruby Ruby函数使用枚举器来获取数字的倍数

Ruby中日期时间和时间的区别