2011-11-14 23 views
8

我有一個數組,看起來像下面這樣:如何在Ruby中執行復雜的自定義排序?

[ 
    { 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

如何按預先確定的規則數組排序?

+1

問題不清楚:什麼是期望的輸出?對於相同類型的產品獲得價格最低的產品?然後總是通過PRICE ASC訂購? – tokland

+1

我認爲他想按照類型進行排序,並且在類型相同的情況下,他希望按價格進行排序。 – sheldonh

+0

@sheldonh。但這正是他的代碼所做的。然後他說,輸出應該命令「BADC」,這是沒有意義的(沒有價格,也沒有輸入順序),但無論如何,似乎B型已經分組,所以他真的想要一些分組。誰知道... – tokland

回答

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"}] 
+0

我認爲通過「BADC」,OP意味着預期的輸出,而不是他事先知道它。但問題不明確。 – tokland

2

問題不明確。這就是我所理解的:訂購主板price ASC,但對於相同類型的主板,只能獲得最便宜的主板。使用構面抽取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"}] 
1

「按組」 您使用的術語令人困惑。

如果你想按類型排序,如果類型是相等的,那麼按價格排序,你可以這樣做:

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

如果沒有,你需要更好地解釋你想要什麼。 :-)