gpt4 book ai didi

ruby - 为什么#each_with_object 和#inject 会切换 block 参数的顺序?

转载 作者:数据小太阳 更新时间:2023-10-29 07:14:08 24 4
gpt4 key购买 nike

#each_with_object#inject都可以用来构建哈希。

例如:

matrix = [['foo', 'bar'], ['cat', 'dog']]

some_hash = matrix.inject({}) do |memo, arr|
memo[arr[0]] = arr
memo # no implicit conversion of String into Integer (TypeError) if commented out
end
p some_hash # {"foo"=>["foo", "bar"], "cat"=>["cat", "dog"]}

another_hash = matrix.each_with_object({}) do |arr, memo|
memo[arr[0]] = arr
end
p another_hash # {"foo"=>["foo", "bar"], "cat"=>["cat", "dog"]}

两者之间的主要区别之一是 #each_with_object 在整个迭代过程中跟踪 memo#inject 设置 memo 等于 block 在每次迭代中返回的值。

另一个区别是顺序或 block 参数。

这里是否传达了某种意图?将两个相似方法的 block 参数取反是没有意义的。

最佳答案

他们有不同的血统。

  • each_with_object 已于 2007 年添加到 Ruby 1.9
  • inject 回到 1980 年的 Smalltalk

我猜想,如果从一开始就使用这两种方法来设计语言,他们可能会期望参数的顺序相同。但事实并非如此。 inject 自 Ruby 出现以来就存在,而 each_with_object 是在 10 年后才添加的。

inject 期望参数的顺序与 Smalltalk 的 inject:into:

相同
collection inject: 0 into: [ :memo :each | memo + each ]

左折叠。你可以把集合想象成一条长长的纸条,从左边向上折叠起来,折叠函数的滑动窗口永远是已经折叠的部分加上剩余纸条的下一个元素

# (memo = 0 and 1), 2, 3, 4  
# (memo = 1 and 2), 3, 4
# (memo = 3 and 3), 4
# (memo = 6 and 4)

当时遵循 Smalltalk 约定是有意义的,因为 Enumerable 中的所有初始方法都来自 Smalltalk,而 Matz 不想让熟悉 Smalltalk 的人感到困惑。

也没有人有先见之明会在 2007 年 each_with_object 被引入 Ruby 1.9 时发生,参数的顺序反射(reflect)了方法名称的词法顺序,即 each ...对象

因此,由于历史原因,这两种方法需要不同顺序的参数。

关于ruby - 为什么#each_with_object 和#inject 会切换 block 参数的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41783001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com