#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","dog"]}
两者之间的关键区别之一是#each_with_object在整个迭代过程中跟踪备忘录,而#inject将memo设置为等于每次迭代时块返回的值.
另一个区别是顺序或块参数.
有没有在这里传达意图?反转两种类似方法的块参数没有意义.
解决方法
他们有不同的血统.
> each_with_object已于2007年添加到Ruby 1.9中
>注入1980年的Smalltalk
我想如果语言是从开头设计的两种方法,他们可能会期望参数顺序相同.但事实并非如此.自从Ruby开始以来,注入已经存在,而every_with_object仅在10年后才被添加.
注入期望参数与Smalltalk注入的顺序相同:into:
collection inject: 0 into: [ :memo :each | memo + each ]
这是左折.您可以将该集合视为从左侧折叠起来的长条纸,折叠功能的滑动窗口始终是已经折叠的部分以及剩余纸条的下一个元素
# (memo = 0 and 1),2,3,4 # (memo = 1 and 2),4 # (memo = 3 and 3),4 # (memo = 6 and 4)
因为Smalltalk会议之所以有意义,因为Enumerable中的所有初始方法都来自Smalltalk,Matz不想让熟悉Smalltalk的人混淆.
任何人都不能有先见之明地知道2007年将each_with_object引入Ruby 1.9并且参数的顺序反映了方法名称的词法顺序,即每个……对象.
因此,由于历史原因,这两种方法期望不同顺序的论证.