2011-11-14 26 views
8

Tôi có một mảng trông giống như sau:Làm cách nào để tôi thực hiện sắp xếp tùy chỉnh phức tạp trong 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' } 
] 

tôi cần phải nhóm này bằng type và sau đó sắp xếp chúng theo ascending price. Tôi nửa có thể giải quyết vấn đề này bằng cách làm như sau:

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

Thật không may, điều này sắp xếp các type s theo thứ tự abc khi họ cần được sắp xếp BADC

Làm thế nào để sắp xếp mảng theo các quy tắc được xác định trước?

+1

câu hỏi không rõ ràng: đầu ra mong muốn là gì? cho các sản phẩm cùng loại có sản phẩm có giá thấp nhất? và sau đó luôn đặt hàng theo PRICE ASC? – tokland

+1

Tôi nghĩ rằng anh ấy muốn sắp xếp theo loại, và nơi loại bằng nhau, anh ấy muốn sau đó sắp xếp theo giá. – sheldonh

+0

@sheldonh. nhưng đó chính xác là mã của anh ấy. Sau đó, ông nói rằng đầu ra nên được đặt hàng "BADC" mà không có ý nghĩa (không có giá cũng không loại thứ tự ở đó ...) nhưng trong mọi trường hợp có vẻ như loại B đã được nhóm lại, vì vậy anh thực sự muốn một số nhóm. Ai biết được ... – tokland

Trả lời

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]} 

Output:

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

Tôi nghĩ rằng bằng "BADC" OP có nghĩa là đầu ra mong đợi, không phải là điều này anh ta biết trước. Nhưng câu hỏi không rõ ràng. – tokland

2

[sửa] Câu hỏi không rõ ràng. Đó là những gì tôi hiểu: bảng đặt hàng của price ASC nhưng đối với các bảng cùng loại, chỉ nhận được giá rẻ nhất. Sử dụng khía cạnh trừu tượng Enumerable#uniq_by (cũng trong ActiveSupport: Array#uniq_by):

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

Output:

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

Việc bạn sử dụng thuật ngữ "nhóm bằng cách" là người gây nhầm lẫn.

Nếu bạn muốn sắp xếp theo loại, và nếu loại bằng sau đó sắp xếp theo giá, bạn có thể làm điều này:

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

Nếu không, bạn sẽ cần phải giải thích rõ hơn những gì bạn muốn. :-)

Các vấn đề liên quan