【发布时间】:2011-12-05 15:41:53
【问题描述】:
myitem.inject({}) {|a,b| a[b.one] = b.two; a}
地点:
myitem 是一个包含数组或配对对象的类(配对对象中有两个字段,一和二)
我不确定上面的代码应该做什么?
【问题讨论】:
myitem.inject({}) {|a,b| a[b.one] = b.two; a}
地点:
myitem 是一个包含数组或配对对象的类(配对对象中有两个字段,一和二)
我不确定上面的代码应该做什么?
【问题讨论】:
从一个空地图开始,将 b.one 键的值设置为 b.two。
换句话说,为“myitem”集合中的每个项目创建一个映射条目。键将是项目的“一”值。该地图条目的值将是项目的“二”值。
给“注入”的块接收两个参数。第一个是“累加器”。在这种情况下,它的初始值是传递给“inject”的空映射。第二个参数是集合中的当前项。在这种情况下,集合中的每个项目。
块必须返回将用作下一个累加器值的任何内容,在本例中为地图。我们希望继续使用同一个映射,所以当我们完成后,“inject”方法将返回包含所有键/值对的映射。
如果不保存注入的结果,这有点毫无价值。
【讨论】:
inject(上述用法的简化)在纯 Ruby 中看起来像这样:def inject(o); each{ |v| o = yield(o,v) }; o; end
def inject(e, o); e.each { ... etc ...
这是一种迂腐的写作方式
h = {}
myitem.each { |b| h[b.one] = b.two }
或者更接近你的原始代码
a = {}
mytem.each { |b| a[b.one] = b.two }
(我个人讨厌这种模式(以及使用它的人),因为它最后需要; a,失去了注入的所有功能方面。(在“功能模式”中使用副作用函数,并且然后意识到后面的函数 (a[..]) 没有返回预期的对象是错误的,IMO)。
Inject 通常用于将列表“折叠”成类似的结果
[1,2,3].inject(0) { |sum, x| sum+x }
=> 6 # (0+1+2+3)
这里sum是最后一次调用块的结果,x是列表中的每个值,0是sum的初始值。
[2,3].inject(10) { |p,x| p*x }
=> 60 # 10*2*3
等等……
【讨论】:
each_with_object你不需要添加; a。
Hash[my_item.map {|object| [object.one, object.two]}]
是另一种方法。
【讨论】: