如何在Ruby中执行复杂的自定义排序?

时间:2011-11-14 13:20:00

标签: ruby sorting

我有一个如下所示的数组:

[
  { type: 'A', price: '0.01' },
  { type: 'B', price: '4.23' },
  { type: 'D', price: '2.29' },
  { type: 'B', price: '3.38' },
  { type: 'C', price: '1.15' }
]

我需要按type对这些进行分组,然后按升序price对其进行排序。我可以通过以下方式解决这个问题:

boards.sort_by {|e| [e['type'], e['price'].to_f]}

不幸的是,这会对type按字母顺序排序BADC

如何按预先确定的规则对数组进行排序?

3 个答案:

答案 0 :(得分:14)

ar=[
  { type: 'A', price: '0.01' },
  { type: 'B', price: '4.23' },
  { type: 'D', price: '2.29' },
  { type: 'B', price: '3.38' },
  { type: 'C', price: '1.15' }
]

SORT_ORDER = 'BADC' #could also be an array, eg ["monday", "tuesday", ...]
p ar.sort_by{|e| [SORT_ORDER.index(e[:type]), e[:price].to_f]}

输出:

[{:type=>"B", :price=>"3.38"},
 {:type=>"B", :price=>"4.23"},
 {:type=>"A", :price=>"0.01"},
 {:type=>"D", :price=>"2.29"},
 {:type=>"C", :price=>"1.15"}]

答案 1 :(得分:2)

[编辑]问题不明确。这就是我的理解:通过price ASC订购电路板,但对于相同类型的电路板,只获得最便宜的电路板。使用Facets的抽象Enumerable#uniq_by(也在ActiveSupport中:Array#uniq_by):

require 'facets'
boards.sort_by { |b| p[:price].to_f }.uniq_by { |b| b[:type] }

输出:

[{:type=>"A", :price=>"0.01"},
 {:type=>"C", :price=>"1.15"},
 {:type=>"D", :price=>"2.29"},
 {:type=>"B", :price=>"3.38"}]

答案 2 :(得分:1)

您对“group by”一词的使用令人困惑。

如果您想按类型排序,如果类型相等然后按价格排序,您可以这样做:

boards.sort do |a, b|
  type_order = a[:type] <=> b[:type]
  if type_order != 0
    type_order
  else
    a[:price] <=> b[:price]
  end
end

如果没有,你需要更好地解释你想要的东西。 : - )