代码之家  ›  专栏  ›  技术社区  ›  Daniel Beardsley

从数组创建哈希的最干净方法

  •  28
  • Daniel Beardsley  · 技术社区  · 17 年前

    我似乎经常遇到这种情况。我需要使用数组中每个对象的属性作为键,从数组中构建一个哈希。

    假设我需要一个使用ActiveRecord对象的哈希值,这些对象由它们的ID设置密钥 常见方式:

    ary = [collection of ActiveRecord objects]
    hash = ary.inject({}) {|hash, obj| hash[obj.id] = obj }
    

    另一种方式:

    ary = [collection of ActiveRecord objects]
    hash = Hash[*(ary.map {|obj| [obj.id, obj]}).flatten]
    

    ary = [collection of ActiveRecord objects]
    hash = ary.to_hash &:id
    #or at least
    hash = ary.to_hash {|obj| obj.id}
    
    5 回复  |  直到 17 年前
        1
  •  64
  •   August Lilleaas    17 年前

    ActiveSupport中已经有一个方法可以执行此操作。

    ['an array', 'of active record', 'objects'].index_by(&:id)
    

    def index_by
      inject({}) do |accum, elem|
        accum[yield(elem)] = elem
        accum
      end
    end
    

    可以重构为(如果您非常需要一行程序):

    def index_by
      inject({}) {|hash, elem| hash.merge!(yield(elem) => elem) }
    end
    
        2
  •  9
  •   zed_0xff    13 年前

    最短的?

    # 'Region' is a sample class here
    # you can put 'self.to_hash' method into any class you like 
    
    class Region < ActiveRecord::Base
      def self.to_hash
        Hash[*all.map{ |x| [x.id, x] }.flatten]
      end
    end
    
        3
  •  8
  •   Fedcomp    9 年前

    以防有人得到普通数组

    arr = ["banana", "apple"]
    Hash[arr.map.with_index.to_a]
     => {"banana"=>0, "apple"=>1}
    
        4
  •  5
  •   ewalshe    17 年前

    class Array
      def to_hash(&block)
        Hash[*self.map {|e| [block.call(e), e] }.flatten]
      end
    end
    
    ary = [collection of ActiveRecord objects]
    ary.to_hash do |element|
      element.id
    end
    
        5
  •  0
  •   Lolindrath    17 年前

    安装 Ruby Facets Gem 并使用他们的 Array.to_h

    推荐文章