0

I got a little problem trying to sort the given of prices and products.

arr = [[6,"iPhone"],[4,"Android"],[5,"iPhone"],[3,"Xbox"],
       [9,"Android"],[8,"Xbox"]]

But i need to sort it by product and then by price. I make the next common to do it:

arr.sort_by! {|x| [x[1],x[0]]}.reverse
 => [[6, "iPhone"], [5, "iPhone"], [8, "Xbox"], [3, "Xbox"], 
     [9, "Android"], [4, "Android"]] 

But i need again to sort it now by the block of products to get the most expensive one block first and so on. The result that I'm looking for its like:

arr = [[9,"Android"],[4,"Android"],[8,"Xbox"],[3,"Xbox"],
       [6,"iPhone"],[5,"iPhone"]]

Any help will be appreciated!

Update 1 I have tested Dave's answer and its works but on other set of items i didn't get the right sort of the block of products.

arr = [[6.0,"iPad 2"], [7, "Mints"], [6.0, "Nerf Crossbow"], [4.5, "iPad 2"],
[6, "Mints"], [6.75, "Nerf Crossbow"], [6.0, "iPad 2"], [5, " Mints"],
[9.0, "Nerf Crossbow"]]

I got this result:

1.9.2p320 :5 >   arr.sort! { |a, b| (a[1] <=> b[1]).nonzero? || b[0] <=> a[0] }  
=> [[7, "Mints"], [6, " Mints"], [5, "Mints"], [9.0, "Nerf Crossbow"], 
[6.75, "Nerf Crossbow"], [6.0, "Nerf Crossbow"], [6.0, "iPad 2"], [6.0, "iPad 2"], 
[4.5, "iPad 2"]]

The problem is that i was expecting

[[9.0, "Nerf Crossbow"], [6.75, "Nerf Crossbow"], [6.0, "Nerf Crossbow"],
[7, "Mints"], [6, "Mints"], [5, "Mints"],[6.0, "iPad 2"], [6.0, "iPad 2"],
[4.5, "iPad 2"]]

2 Answers 2

4

Simple, just negate the price:

arr.sort_by! {|price, product| [product.downcase, -price]}

This is clearer and faster than using sort. I added downcase to the product name as you probably shouldn't care about the case.

Sign up to request clarification or add additional context in comments.

3 Comments

It gives a wildly different result, however.
@DaveNewton: Oups, didn't notice I needed to reverse the order of the elements. Fixed.
+1 Far clearer what's going on here and doesn't introduce excessive logic.
3

Here's another option:

arr.sort_by { |e| [e[1], -e[0]] }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.