[英]How do I convert an array of hashes into a sorted hash?
如果我有一系列哈希,每個哈希都有一個天鍵:
[
{:day=>4,:name=>'Jay'},
{:day=>1,:name=>'Ben'},
{:day=>4,:name=>'Jill'}
]
將日期轉換為以日期值作為鍵的哈希值的最佳方法是什么:
{
:1=>[{:day=>1,:name=>'Ben'}],
:4=>[{:day=>4,:name=>'Jay'},{:day=>4,:name=>'Jill'}]
}
我正在使用Ruby 1.9.2和Rails 3.1.1
就我個人而言,直到我真正需要時,我才開始打擾“排序”鍵(相當於在Ruby 1.9中按輸入順序排序)。 然后,您可以使用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"}]}
而是在實際需要時對鍵進行排序。
假設您將數組稱為list
,這是使用reduce
方法的一種方法:
list.reduce({}) { |hash, item|
(hash[item[:day]] ||= []) << item; hash
}
這是另一個使用map
方法的方法,但是您必須隨身攜帶一個holder變量:
hash = {}
list.each { |item|
(hash[item[:day]] ||= []) << item
}
在變量foo
輸入未排序的哈希值后,您可以將其排序為,
Hash[foo.sort]
簡單答案:
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
該解決方案的問題:哈希未按要求排序。 (同樣的問題有Anurags解決方案 )。
因此,您必須稍微修改一下答案:
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
在Rails中,您可以使用OrderedHash
:
ActiveSupport::OrderedHash[arr.group_by { |a| a[:day] }.sort_by(&:first)]
更新:實際上,在Ruby 1.9中哈希是有序的,因此不需要使用ActiveSupport
擴展:
Hash[arr.group_by { |a| a[:day] }.sort_by(&:first)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.