From: "David A. Black" Date: 2009-08-30T20:14:48+09:00 Subject: Re: Sorting an array by multiple elements? Hi -- On Sun, 30 Aug 2009, Josh Cheek wrote: > On Sun, Aug 30, 2009 at 1:30 AM, Paul wrote: > >> Hi there, I have an array of arrays that I want to sort by multiple >> elements. >> >> Sample data in the array looks like: [ [ id, date, num, name ], [ id, >> date, num, name ], ... ] >> >> I need to sort by : (1) name, (2) date, and (3) id. >> >> I can sort by any one element in the array no problem using something >> like : >>> summary_data.sort! { |a,b| a[ 3 ] <=> b[ 3 ] } >> >> Unfortunately, I can't do this line more than once because it blows >> away any previous sorting. >> >> I found a few pages on the internet that describe how to "sort an >> array of Ruby objects by multiple class fields", however, I don't know >> how to create a "class field". I'm looking at an array, not a class. >> >> Is there a way to do this or do I need to convert my data to something >> else so I can do what I need? >> >> Please help. >> >> Thanks. >> >> > > data = [ [ 1 , Time.now , 4, "barny" ] , > [ 1 , Time.now , 1, "cliff" ] , > [ 2 , Time.now , 3, "alfie" ] , > [ 2 , Time.now , 2, "alfie" ] ] > > #you can assign the values of the arrays to specific names by grouping > data.sort do |(a_id,a_date,a_num,a_name) , (b_id,b_date,b_num,b_name)| > > first = a_id <=> b_id #first condition > second = a_num <=> b_num #second condition > > first.zero? ? second : first #if they are equal on first > #then return second You can also do: first.nonzero? || second which I like the look of though I find myself having to kind of step through it mentally to keep track.... I agree with botp, though, that it's a good case for #sort_by: data.sort_by {|id, date, num, name| [id, date, num] } David -- David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com Ruby/Rails training, mentoring, consulting, code-review Latest book: The Well-Grounded Rubyist (http://www.manning.com/black2) September Ruby training in NJ has been POSTPONED. Details to follow.