Самый чистый способ создания хэша из массива
Кажется, я часто сталкивался с этим. Мне нужно построить хэш из массива, используя атрибут каждого объекта в массиве в качестве ключа.
Предположим, что мне нужен хэш примера, использует объекты ActiveRecord, привязанные их идентификаторами
Обычный способ:
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]
Мечта:
Я мог бы и мог бы создать это сам, но есть ли что-нибудь в Ruby или Rails, что это будет?
ary = [collection of ActiveRecord objects]
hash = ary.to_hash &:id
#or at least
hash = ary.to_hash {|obj| obj.id}
Ответы
Ответ 1
В 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
кратчайший?
# '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
Вы можете добавить to_hash в Array самостоятельно.
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
Ответ 4
Если кто-то получил простой массив
arr = ["banana", "apple"]
Hash[arr.map.with_index.to_a]
=> {"banana"=>0, "apple"=>1}
Ответ 5
Установите Ruby Facets Gem и используйте Array.to_h.