【问题标题】:Having a hard time understanding & implementing some Ruby code很难理解和实现一些 Ruby 代码
【发布时间】:2011-12-05 15:41:53
【问题描述】:
myitem.inject({}) {|a,b| a[b.one] = b.two; a}

地点:

myitem 是一个包含数组或配对对象的类(配对对象中有两个字段,一和二)

我不确定上面的代码应该做什么?

【问题讨论】:

    标签: ruby inject


    【解决方案1】:

    从一个空地图开始,将 b.one 键的值设置为 b.two。

    换句话说,为“myitem”集合中的每个项目创建一个映射条目。键将是项目的“一”值。该地图条目的值将是项目的“二”值。

    给“注入”的块接收两个参数。第一个是“累加器”。在这种情况下,它的初始值是传递给“inject”的空映射。第二个参数是集合中的当前项。在这种情况下,集合中的每个项目。

    块必须返回将用作下一个累加器值的任何内容,在本例中为地图。我们希望继续使用同一个映射,所以当我们完成后,“inject”方法将返回包含所有键/值对的映射。

    如果不保存注入的结果,这有点毫无价值。

    【讨论】:

    • 那么实际的注入会是什么样子?我的意思是实际的方法
    • @JeremyGuy 它还需要在方法结束时返回“o”。不过,对于这个用例,它或多或少像 phrogz 所写的那样正确。
    • inject(上述用法的简化)在纯 Ruby 中看起来像这样:def inject(o); each{ |v| o = yield(o,v) }; o; end
    • @JeremyGuy 这是 Enumerable (或数组,或其他)上的方法,而不是独立的。如果你想把它写成一个独立的方法,你还需要传入枚举:def inject(e, o); e.each { ... etc ...
    【解决方案2】:

    这是一种迂腐的写作方式

    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是列表中的每个值,0sum的初始值。

    [2,3].inject(10) { |p,x| p*x }
    => 60 # 10*2*3
    

    等等……

    【讨论】:

    • 注入有什么作用?我真的不明白
    • 使用它的原因是为了链接; each 不返回哈希值。
    • 换句话说,我不认为“迂腐”在这里真的有意义。
    • 如果oyu使用1.9的each_with_object你不需要添加; a
    • @dave 我认为是的。这是迂腐的,因为它是简单代码的复杂版本。我的意思是复杂,不是直接理解(因为它值得在这里提出一个问题)并且没有任何好处。链接的好处(并避免在最简单的版本中使用 '; h')因为你确实添加了 '; a'在注入。我见过很多这种模式,也看到很多人忘记了';一个'
    【解决方案3】:
    Hash[my_item.map {|object| [object.one, object.two]}]
    

    是另一种方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多