How to execute a complex custom look in Ruby?

I have an array that looks like this:

[ { 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' } ] 

I need to group them with type and then sort them in ascending price . I can solve this problem in half by following these steps:

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

Unfortunately, this sorts type in alphabetical order when they should be sorted by BADC

How to sort an array according to predefined rules?

+8
sorting ruby
source share
3 answers
 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"}] 
+14
source share

[edit] The question is not clear. What I understand: order price ASC boards, but for boards of the same type, get only the cheapest. Using the Facets Enumerable # uniq_by abstraction (also in 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"}] 
+2
source share

Your use of the term "group by" is embarrassing to people.

If you want to sort by type, and if the type is equal, then sort by price, you can do this:

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

If not, you need to better explain what you want. :-)

+1
source share

All Articles