在ruby中对哈希数组进行排序

时间:2012-03-21 15:26:22

标签: ruby sorting

我有一系列哈希看起来像:

ward = {id: id, name: record["Externalization"], mnemonic: record["Mnemonic"],
   seqno: record["SeqNo"]}

所有字段都是字符串。

现在我想先在seqno然后在名字上对它们进行排序。 seqno可以是nil(如果seqno是nil,那么这个病房必须在有seqno的病房之后)。

到目前为止我所拥有的是:

wardList.sort! do |a,b| 
  return (a[:name] <=> b[:name]) if (a[:seqno].nil? && b[:seqno].nil?) 
  return -1 if a[:seqno].nil?
  return 1 if b[:seqno].nil?
  (a[:seqno] <=> b[:seqno]).nonzero? ||
    (a[:name] <=> b[:name])
end

但是这给了我错误:无法将符号转换为整数

3 个答案:

答案 0 :(得分:2)

首先,规范化您的数据,您不能在这里使用整数作为字符串:

wardList = wardList.map { |x| x.merge({:id    => x[:id].to_i, 
                                       :seqno => x[:seqno].try(:to_i) }) }

然后你可以使用支持词典排序的sort_by

wardList.sort_by! { |x| [x[:seqno] || Float::INFINITY, x[:name]] }

示例:

irb(main):034:0> a = [{:seqno=>5, :name=>"xsd"}, 
                      {:seqno=>nil, :name=>"foo"}, 
                      {:seqno=>nil, :name=>"bar"}, 
                      {:seqno=>1, :name=>"meh"}]
irb(main):033:0> a.sort_by { |x| [x[:seqno] || Float::INFINITY, x[:name]] }
=> [{:seqno=>1, :name=>"meh"},
    {:seqno=>5, :name=>"xsd"},
    {:seqno=>nil, :name=>"bar"},
    {:seqno=>nil, :name=>"foo"}]

答案 1 :(得分:1)

这应该有效:

sorted = wardList.sort_by{|a| [a[:seqno] ? 0 : 1, a[:seqno], a[:name]] }

或某些红宝石(例如1.8.7):

sorted = wardList.sort_by{|a| [a[:seqno] ? 0 : 1, a[:seqno] || 0, a[:name]] }

答案 2 :(得分:0)

我认为你不应该在这里使用return,它会导致块返回迭代器,迭代器返回封闭方法,封闭方法返回其调用者。使用next代替只导致块返回迭代器(在这种情况下为sort!)并执行以下操作:

wardList.sort! do |x,y|
  next  1 if x[:seqno].nil?
  next -1 if y[:seqno].nil?
  comp = x[:seqno] <=> y[:seqno]
  comp.zero? ? x[:name] <=> y[:name] : comp
end