/ / Ako prevediem pole hashov na triedený hash? - rubín-on-rails, rubín, polia, hash

Ako konvertujem pole hashov do triedeného hash? - ruby ​​na koľajniciach, rubín, poliach, hash

Ak mám pole hashov, každý s denným kľúčom:

[
{:day=>4,:name=>"Jay"},
{:day=>1,:name=>"Ben"},
{:day=>4,:name=>"Jill"}
]

Aký je najlepší spôsob prevodu na hash s hodnotami zoradených dní ako kľúčmi:

{
:1=>[{:day=>1,:name=>"Ben"}],
:4=>[{:day=>4,:name=>"Jay"},{:day=>4,:name=>"Jill"}]
}

Používam Ruby 1.9.2 a Rails 3.1.1

odpovede:

4 pre odpoveď č. 1

Osobne by som sa neobťažoval „triediť“ kľúče (čo predstavuje čas objednania podľa času v Ruby 1.9), kým to skutočne nebudem potrebovať. Potom môžete použiť group_by:

arr = [{:day=>4,:name=>"Jay"}, {:day=>1,:name=>"Ben"}, {:day=>4,:name=>"Jill"}]
arr.group_by { |a| a[:day] }
=> {4=>[{:day=>4, :name=>"Jay"}, {:day=>4, :name=>"Jill"}],
1=>[{:day=>1, :name=>"Ben"}]}

Namiesto toho kľúče triedte, keď ich skutočne potrebujete.


1 pre odpoveď č. 2

Za predpokladu, že sa vaše pole volá, je list, tu je jeden spôsob použitia reduce metóda:

list.reduce({}) { |hash, item|
(hash[item[:day]] ||= []) << item; hash
}

Tu je ďalší, ktorý používa map metódou, ale musíte nosiť nosnú premennú okolo:

hash = {}
list.each { |item|
(hash[item[:day]] ||= []) << item
}

Keď budete mať netriedený hash povedzte v premennej foo, môžete to triediť ako,

Hash[foo.sort]

0 pre odpoveď č. 3

Jednoduchá odpoveď:

data = [
{:day=>4,:name=>"Jay"},
{:day=>1,:name=>"Ben"},
{:day=>4,:name=>"Jill"}
]

#expected solution
sol = {
1=>[{:day=>1,:name=>"Ben"}],
4=>[{:day=>4,:name=>"Jay"},{:day=>4,:name=>"Jill"}]
}

res = {}
data.each{|h|
res[h[:day]] ||=  []
res[h[:day]] << h
}

p res
p res == sol    #check value
p res.keys == sol.keys  #check order

Problém s týmto riešením: Hodnota hash nie je zoradená podľa požiadaviek. (Rovnaký problém má Anuragovo riešenie).

Odpoveď teda musíte trochu upraviť:

res = {}
data.sort_by{|h| h[:day]}.each{|h|
res[h[:day]] ||=  []
res[h[:day]] << h
}

p res
p res == sol    #check value
p res.keys == sol.keys  #check order

0 pre odpoveď č. 4

V Rails môžete použiť OrderedHash:

ActiveSupport::OrderedHash[arr.group_by { |a| a[:day] }.sort_by(&:first)]

aktualizácia: V skutočnosti je v Ruby 1.9 objednaný hash, takže pomocou ActiveSupport rozšírenie nie je potrebné:

Hash[arr.group_by { |a| a[:day] }.sort_by(&:first)]