The approach with multiplying is fragile. I would prefer one of these
approaches:
10:03:18 tmp$ cat x.rb
require 'pp'
data = [
["DEF-1", 1271772000, 1],
["ABC-2", 1271773800, 1],
["ABC-3", 1271863200, 2],
["AAA-1", 1271862000, 2],
["ABC-4", 1271869200, 2],
["ABC-1", 1271768400, 2]
]
pp data.sort_by {|x| [x[1], x[0]]}
pp data.sort do |(la,ta,na),(lb,tb,nb)|
c = ta <=> tb
c == 0 ? la <=> lb : c
end
10:03:24 tmp$ ruby19 x.rb
[["ABC-1", 1271768400, 2],
["DEF-1", 1271772000, 1],
["ABC-2", 1271773800, 1],
["AAA-1", 1271862000, 2],
["ABC-3", 1271863200, 2],
["ABC-4", 1271869200, 2]]
[["AAA-1", 1271862000, 2],
["ABC-1", 1271768400, 2],
["ABC-2", 1271773800, 1],
["ABC-3", 1271863200, 2],
["ABC-4", 1271869200, 2],
["DEF-1", 1271772000, 1]]
10:03:26 tmp$
However, as Jeremy said already, using specific classes is much more
preferable because it makes the code easier to read and less error
prone. In this case it can be as simple as
10:13:34 tmp$ cat y.rb
require 'pp'
Booking = Struct.new :label, :timestamp, :room do
include Comparable
# defines default ordering:
# 1. timestamp
# 2. label
def <=> o
c = timestamp <=> o.timestamp
c == 0 ? label <=> o.label : c
end
end
data = [
Booking["DEF-1", 1271772000, 1],
Booking["ABC-2", 1271773800, 1],
Booking["ABC-3", 1271863200, 2],
Booking["AAA-1", 1271862000, 2],
Booking["ABC-4", 1271869200, 2],
Booking["ABC-1", 1271768400, 2]
]
pp data.sort
10:13:37 tmp$ ruby19 y.rb
[#<struct Booking label="ABC-1", timestamp=1271768400, room=2>,
#<struct Booking label="DEF-1", timestamp=1271772000, room=1>,
#<struct Booking label="ABC-2", timestamp=1271773800, room=1>,
#<struct Booking label="AAA-1", timestamp=1271862000, room=2>,
#<struct Booking label="ABC-3", timestamp=1271863200, room=2>,
#<struct Booking label="ABC-4", timestamp=1271869200, room=2>]
10:13:41 tmp$
Btw, I'd also use Time instances for the timestamps but class Booking
also works with Fixnums which you have in your data.
Kind regards
robert
···
On Thu, Sep 23, 2010 at 10:45 PM, (r.*n){2} <perl2ruby@gmail.com> wrote:
On Sep 23, 11:27 am, Jeremy Bopp <jer...@bopp.net> wrote:
On 9/22/2010 11:30 PM, Paul wrote:
> Hi Jeremy, thanks for the reply.
> On Sep 22, 6:54 pm, Jeremy Bopp <jer...@bopp.net> wrote:
>>> You could define a class to represent each of your inner array elements.
>>> That class could then define the <=> method in which you could compare
>>> each item in the order you desire. Then your outer array, consisting of
>>> instances of your class, could be trivially sorted with Array#sort.
> I'm afraid I don't understand what you are saying here. All I
> understood was "could be trivially sorted with Array#sort." I don't
> understand classes.
Classes are rather a central concept in Ruby, so it would be a really
good idea to learn about them; however, they are not necessary here.
I'll keep this short and say that using an array of arrays such as what
you have here can make your code cryptic and brittle as it grows and
ages. Using a class to represent your inner array items will help avoid
these issues. 
I see that you have more details about your problem in a later reply, so
I'll see about addressing more issues there.
-Jeremy
$cat h1.rb
#!/usr/bin/ruby
puts [
["DEF-1", 1271772000, 1],
["ABC-2", 1271773800, 1],
["ABC-3", 1271863200, 2],
["AAA-1", 1271862000, 2],
["ABC-4", 1271869200, 2],
["ABC-1", 1271768400, 2]
].sort{ |x,y| (x[1] <=> y[1]) * 10 + (x[0] <=> y[0]) }.inspect
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/