簡體   English   中英

如何將哈希數組轉換為排序的哈希?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM