Problem with sort!

(Vance A Heron) #1

Hello,
I'm having a problem using sort! to sort an array
in which each element is an array. I tried to generate
a short example, and am getting different, but still
puzzling behavior. In my real program, the error I get
is:

bin/newr2r.rb:107:in `sort': comparison of Array with Array failed
(ArgumentError)

Any help understanding this would be appreciated.
Thanks,
Vance

Short example:

···

---
#! /usr/bin/env ruby

a = [ ["Car", "Drive"], ["Boat", "Sail"], ["Plane", "Fly"] ]

puts "Original Array"
a.each{|v| p v}

puts "\nSort to new array"
b = a.sort{ |a, b| a[0] <=> b[0] }
b.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}

puts "\nSort to self"
a.sort!{ |a, b| a[0] <=> b[0] }
a.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}
---
Output from run...
SUN:quigon> sortprob.rb
Original Array
["Car", "Drive"]
["Boat", "Sail"]
["Plane", "Fly"]

Sort to new array
class(Array) Boat, Sail
class(Array) Car, Drive
class(Array) Plane, Fly

Sort to self
class(String) 67, 97

(Jason Foreman) #2

Hello,
I'm having a problem using sort! to sort an array
in which each element is an array. I tried to generate
a short example, and am getting different, but still
puzzling behavior. In my real program, the error I get
is:
> bin/newr2r.rb:107:in `sort': comparison of Array with Array failed
> (ArgumentError)

Any help understanding this would be appreciated.
Thanks,
Vance

Short example:
---
#! /usr/bin/env ruby

a = [ ["Car", "Drive"], ["Boat", "Sail"], ["Plane", "Fly"] ]

puts "Original Array"
a.each{|v| p v}

puts "\nSort to new array"
b = a.sort{ |a, b| a[0] <=> b[0] }
b.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}

puts "\nSort to self"
a.sort!{ |a, b| a[0] <=> b[0] }
a.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}
---

Don't use a as the variable name inside the block. You are
overwriting your original variable a when you do this.

a.sort {|x, y| ...} or something else...

Jason

···

On 8/19/05, Vance A Heron <heron@jpl.nasa.gov> wrote:

Output from run...
SUN:quigon> sortprob.rb
Original Array
["Car", "Drive"]
["Boat", "Sail"]
["Plane", "Fly"]

Sort to new array
class(Array) Boat, Sail
class(Array) Car, Drive
class(Array) Plane, Fly

Sort to self
class(String) 67, 97

(David A. Black) #3

Hi --

···

On Sat, 20 Aug 2005, Vance A Heron wrote:

Hello,
I'm having a problem using sort! to sort an array
in which each element is an array. I tried to generate
a short example, and am getting different, but still
puzzling behavior. In my real program, the error I get
is:

bin/newr2r.rb:107:in `sort': comparison of Array with Array failed
(ArgumentError)

Any help understanding this would be appreciated.
Thanks,
Vance

Short example:
---
#! /usr/bin/env ruby

a = [ ["Car", "Drive"], ["Boat", "Sail"], ["Plane", "Fly"] ]

puts "Original Array"
a.each{|v| p v}

puts "\nSort to new array"
b = a.sort{ |a, b| a[0] <=> b[0] }
b.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}

puts "\nSort to self"
a.sort!{ |a, b| a[0] <=> b[0] }
a.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}

Don't use the same variable name (a) for your block variables. You're
trampling the array a. I think that's the root of your problems.

David

--
David A. Black
dblack@wobblini.net

(W. James) #4

Vance A Heron wrote:

puts "\nSort to new array"
b = a.sort{ |a, b| a[0] <=> b[0] }
b.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}

It's simpler with sort_by:

b = a.sort_by{ |x| x[0] }

(Vance A Heron) #5

The real function was a little more complex than
could be done by sort by. I tried to generate
a smaller example, and confused myself.

I refactored a little to reduce duplicating
code - basically I have 2 separate sort methods,
depending on a value in the data - but they're
substantially the same. Anyway, by putting
the common code in a method and having sort
do something like vals.sort!{|a,b| sortfunc(a,b,sortflag) }
things seem to work.

Thanks to the list for all the help.

Hopefully my next problem/puzzle will be more
interesting.

V

···

On Sat, 2005-08-20 at 10:26 +0900, William James wrote:

Vance A Heron wrote:

> puts "\nSort to new array"
> b = a.sort{ |a, b| a[0] <=> b[0] }
> b.each{|v| puts "class(#{v.class}) #{v[0]}, #{v[1]}"}

It's simpler with sort_by:

b = a.sort_by{ |x| x[0] }