代码之家  ›  专栏  ›  技术社区  ›  Jeff Ancel

Ruby Array.inject问题-无法查看

  •  4
  • Jeff Ancel  · 技术社区  · 15 年前

    [1, 2, 3, 4].inject({}) {|result, e| result[e] = 0} 
    

    这就是我得到的错误。

    oMethodError: undefined method `[]=' for 0:Fixnum
        from (irb):1
        from (irb):1:in `inject'
        from (irb):1:in `each'
        from (irb):1:in `inject'
        from (irb):1
        from :0
    
    6 回复  |  直到 15 年前
        1
  •  8
  •   ezpz    15 年前

    问题是 result[e] = 0 返回操作的结果,即0,并将其带到下一次迭代中,在该迭代中尝试调用 []= 在上面。您可以通过执行以下操作来克服此问题:

    [1, 2, 3, 4].inject({}) {|result, e| result[e] = 0; result }

        2
  •  8
  •   glenn mcdonald    15 年前

    “结果”很好,但就口味而言,我更喜欢这种方式:

    [1,2,3,4].inject({}) {|result,e| result.merge!(e=>0)}
    

    但是,如果这是性能关键型代码,那么taste也有它的价格。下面是一个快速的基准测试,它可以执行此操作一百万次。

    merge: 22s
    merge!: 14s
    ; result: 9s
    

    在Ruby 1.9.1中

    merge: 18s
    merge!: 11s
    ; result: 5s
    
        3
  •  2
  •   sepp2k    15 年前

    result[e] = 0 result . 你必须做到:

    [1, 2, 3, 4].inject({}) {|result, e| result[e] = 0; result}
    

    (或使用 merge []= 或使用 each 而不是 inject )

        4
  •  0
  •   guitarzan guitarzan    15 年前

    [1,2,3,4].inject({}) {|result,e| result.merge!(e=>0)}
    
        5
  •  0
  •   Andrew Grimm atk    15 年前

    这需要两行,但你也可以

    hash = {}
    [1,2,3,4].each{|key| hash[key] = 0}
    
        6
  •  0
  •   Bert    15 年前

    如果您的数组是一个没有嵌套其他数组的简单数组,那么我将使用数组解引用哈希构造方法:

    Hash[*[1,2,3,4].zip(Array.new(4,0)).flatten]
    

    或者可能更一般化:

    如果存在嵌套数组,则只需展平一层深度,而且由于没有用于展平\u的ruby命令,因此只需通过串联手动执行即可。好处是,您可以在串联过程中交错零,这样您就不必再压缩它了:

    Hash[*[1,2,3,4].inject([]){|s,x| s.concat([x,0])}]
    

    aforementioned merge! method:       34s
    Hash[*...).concat([x,0])}] method:  25s
    aforementioned result! method:      22s
    Hash[*...).flatten] method:         15s