modo più pulito per creare un hash da una matrice

voti
27

Mi sembra di correre in questo molto spesso. Ho bisogno di costruire un hash da un array utilizzando un attributo di ciascun oggetto nell'array come chiave.

Diciamo che ho bisogno di un hash di esempio utilizza objecs ActiveRecord digitato da loro ID modo comune:

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

Un altro modo:

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

Sogno Way: ho potuto e potrebbe creare questo me stesso, ma c'è qualcosa in Ruby o Rails che sarà questo?

ary = [collection of ActiveRecord objects]
hash = ary.to_hash &:id
#or at least
hash = ary.to_hash {|obj| obj.id}
È pubblicato 05/01/2009 alle 11:44
fonte dall'utente
In altre lingue...                            


5 risposte

voti
5

È possibile aggiungere to_hash a Array te stesso.

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
Risposto il 05/01/2009 a 12:52
fonte dall'utente

voti
51

C'è già un metodo in ActiveSupport che fa questo.

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

E solo per la cronaca, ecco l'attuazione:

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

Che avrebbero potuto essere refactoring in (se siete alla disperata ricerca di one-liner):

def index_by
  inject({}) {|hash, elem| hash.merge!(yield(elem) => elem) }
end
Risposto il 05/01/2009 a 13:17
fonte dall'utente

voti
0

Installare il rubino Sfaccettature Gem e utilizzare il loro Array.to_h .

Risposto il 05/01/2009 a 18:14
fonte dall'utente

voti
8

uno più breve?

# '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
Risposto il 14/04/2013 a 23:44
fonte dall'utente

voti
4

Nel caso in cui qualcuno ha ottenuto matrice pianura

arr = ["banana", "apple"]
Hash[arr.map.with_index.to_a]
 => {"banana"=>0, "apple"=>1}
Risposto il 10/03/2017 a 14:15
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more