我有两个数组,一个哈希数组另一个数组。我需要使哈希数组与键数组的顺序相同。我怎么能这样做
header = ["header1", "header2", "header3", "header4", "header5"]
record = [{"header4" =>"value4"}, {"header3" =>"value3"}, {"header5"=>"value5"}, {"header1"=>"value1"}, {"header2"=>"value2"}]
我需要将数组记录放入与数组头
相同的顺序record = [{"header1" =>"value1"}, {"header2" =>"value2"}, {"header3"=>"value3"}, {"header4"=>"value4"}, {"header5"=>"value5"}]
非常感谢每一个人的帮助。我想在这篇文章中再添一个问题。 我正在尝试使用下面建议的方法从数据库创建CSV文档。所以我想按特定顺序组织列,我有这个顺序的模板,这个模板存储为标题数组,但是当我这样做时
csv<< mymodel.attributes.values.sort_by! { |h| header.index(h.keys[0])
不起作用
答案 0 :(得分:5)
Array#sort_by!
/ Enumerable#sort_by
接受一个阻止。块的返回值用于比较。对于您的情况,您可以使用Array#index
。
header = ["header1", "header2", "header3", "header4", "header5"]
record = [{"header4" =>"value4"}, {"header3" =>"value3"},
{"header5"=>"value5"}, {"header1"=>"value1"},
{"header2"=>"value2"}]
record.sort_by! { |h| header.index(h.keys[0]) }
# => [{"header1"=>"value1"}, {"header2"=>"value2"}, {"header3"=>"value3"},
# {"header4"=>"value4"}, {"header5"=>"value5"}]
答案 1 :(得分:1)
我会像@falsetru那样做,但这是另一种方式:
record.each_with_object({}) { |h,g| g[h.keys.first] = h }.values_at(*header)
#=> [{"header1"=>"value1"}, {"header2"=>"value2"}, {"header3"=>"value3"},
# {"header4"=>"value4"}, {"header5"=>"value5"}]
答案 2 :(得分:0)
对于这个简单的对象,你真的不需要额外的数组,因为这将起作用
record.sort_by do |hash|
hash.keys.find{|key| key=~ /header/}.scan(/\d+/).pop.to_i
end
#=> [{"header1"=>"value1"}, {"header2"=>"value2"}, {"header3"=>"value3"}, {"header4"=>"value4"}, {"header5"=>"value5"}]
我有一种感觉,虽然这个问题被剥夺了要点,但我想无论如何我会告诉你。由于您只想按标题编号排序,因此会找到标题键,然后scan
将数字弹出最后一个并转换为Integer
进行排序。因此,它适用于Hash
或"header1"
"header1432"
答案 3 :(得分:0)
以上答案都很棒,但没有一个在O(n)时间内执行操作。我认为可以通过将>> record_h = record.reduce(:merge)
=> {"header4"=>"value4", "header3"=>"value3", "header5"=>"value5", "header1"=>"value1", "header2"=>"value2"}
转换为临时哈希来提高理论性能和清晰度:
>> header.map{|h| {h => record_h[h]}}
=> [{"header1"=>"value1"}, {"header2"=>"value2"}, {"header3"=>"value3"}, {"header4"=>"value4"}, {"header5"=>"value5"}]
-
JSESSIONID