Sort pseudo-lists

P

pete boardman

Say I've got a string like this:

"{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2, 2.1, 4.2}}"

- imagine it's aspiring to be a list of sublists, with 4 reals in
each list. I want to produce a sorted version:

(1.4 2.2 2.1 4.2)
(2.1 3.14 2.4 2.2)
(3.1 1.3 2.5 2.1)

What would be a good way to do this?

thanks

Pete
 
J

James Edward Gray II

Say I've got a string like this:

"{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2, 2.1, 4.2}}"

- imagine it's aspiring to be a list of sublists, with 4 reals in
each list. I want to produce a sorted version:

(1.4 2.2 2.1 4.2)
(2.1 3.14 2.4 2.2)
(3.1 1.3 2.5 2.1)

What would be a good way to do this?

Well, if you can count on the data format, the following is pretty
simple:

irb(main):001:0> arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4,
2.2}, {1.4, 2.2, 2.1, 4.2}}".tr("{}", "[]")
=> [[3.1, 1.3, 2.5, 2.1], [2.1, 3.1, 2.4, 2.2], [1.4, 2.2, 2.1, 4.2]]
irb(main):002:0>
irb(main):003:0* arr.sort { |a, b| a.first <=> b.first }
=> [[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]

Hope that helps.

James Edward Gray II
 
A

Ara.T.Howard

Say I've got a string like this:

"{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2, 2.1, 4.2}}"

- imagine it's aspiring to be a list of sublists, with 4 reals in each list.
I want to produce a sorted version:

(1.4 2.2 2.1 4.2)
(2.1 3.14 2.4 2.2)
(3.1 1.3 2.5 2.1)

What would be a good way to do this?

harp:~ > cat a.rb
buf = "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2, 2.1, 4.2}}"
buf.gsub! %r/ { /x, ' [ '
buf.gsub! %r/ } /x, ' ] '

require 'yaml'
list = YAML::load(buf).map{|s| s.sort}.sort

p list

harp:~ > ruby a.rb
[[1.3, 2.1, 2.5, 3.1], [1.4, 2.1, 2.2, 4.2], [2.1, 2.2, 2.4, 3.1]]


-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
P

pete boardman

arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2,
2.1, 4.2}}".tr("{}", "[]")
arr.sort { |a, b| a.first <=> b.first }

Thanks, James - simple, elegant, and nearly perfect! Is it easy to
sort the array of arrays by their second, third, and fourth entries
as well:

ie such that

[[2.1, 2.2, 9.5, 2.1], [2.1, 2.2, 2.4, 2.2], [2.1, 2.2, 2.1, 4.2]]

sorts to

[[2.1, 2.2, 2.1, 4.2],[2.1, 2.2, 2.4, 2.2],[2.1, 2.2, 9.5, 2.1]]

rather than

[[2.1, 2.2, 9.5, 2.1], [2.1, 2.2, 2.4, 2.2], [2.1, 2.2, 2.1, 4.2]]

thanks

Pete
 
M

Martin DeMello

pete boardman said:
arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2,
2.1, 4.2}}".tr("{}", "[]")
arr.sort { |a, b| a.first <=> b.first }

Thanks, James - simple, elegant, and nearly perfect! Is it easy to
sort the array of arrays by their second, third, and fourth entries
as well:

That's actually the default behaviour, so you can just say arr.sort

martin
 
W

William James

pete said:
Is it easy to
sort the array of arrays by their second, third, and fourth entries
as well:

ie such that

[[2.1, 2.2, 9.5, 2.1], [2.1, 2.2, 2.4, 2.2], [2.1, 2.2, 2.1, 4.2]]

sorts to

[[2.1, 2.2, 2.1, 4.2],[2.1, 2.2, 2.4, 2.2],[2.1, 2.2, 9.5, 2.1]]

rather than

[[2.1, 2.2, 9.5, 2.1], [2.1, 2.2, 2.4, 2.2], [2.1, 2.2, 2.1, 4.2]]

thanks

Pete

a = "{{2.1, 2.2, 9.5, 2.1}, {2.1, 2.2, 2.4, 2.2}, {2.1, 2.2, 2.1,
4.2}}"\
[2..-3].split( '}, {' ).map{|x| x.split( /,\s+/ ).map{|s| s.to_f } }
p a.sort
 
W

William James

James said:
irb(main):001:0> arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4,
2.2}, {1.4, 2.2, 2.1, 4.2}}".tr("{}", "[]")
=> [[3.1, 1.3, 2.5, 2.1], [2.1, 3.1, 2.4, 2.2], [1.4, 2.2, 2.1, 4.2]]
irb(main):002:0>
irb(main):003:0* arr.sort { |a, b| a.first <=> b.first }
=> [[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]

arr.sort_by{|x| x.first }
 
D

David A. Black

Hi --

irb(main):001:0> arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4,
2.2}, {1.4, 2.2, 2.1, 4.2}}".tr("{}", "[]")
=> [[3.1, 1.3, 2.5, 2.1], [2.1, 3.1, 2.4, 2.2], [1.4, 2.2, 2.1, 4.2]]
irb(main):002:0>
irb(main):003:0* arr.sort { |a, b| a.first <=> b.first }
=> [[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]

arr.sort_by{|x| x.first }

Better yet:

arr.sort

which will handle tie-breaks automatically.


David
 
P

pete boardman

One more thing - I forgot that I need to get the result back to a
string... So (thanks to your help andn Ruby's 'eval') I can go from
this:

"{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2, 2.1, 4.2}}"

to this:

[[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]

but I can't persuade the 'p' method to turn this back into a string:

"[[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]"

(and I should be able to go from here to :

"{{1.4, 2.2, 2.1, 4.2}, {2.1, 3.1, 2.4, 2.2}, {3.1, 1.3, 2.5, 2.1}}"

on my own :)


Pete
 
R

Robert Klemme

Martin said:
pete boardman said:
arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2,
2.1, 4.2}}".tr("{}", "[]")
arr.sort { |a, b| a.first <=> b.first }

Thanks, James - simple, elegant, and nearly perfect! Is it easy to
sort the array of arrays by their second, third, and fourth entries
as well:

That's actually the default behaviour, so you can just say arr.sort

Strictly speaking that's wrong: the code above and arr.sort are not
equivalent because arr.sort will evaluate all elements of embedded arrays
while the code above will only honor the first one:
a=[[1,2,3],[1,0,0]] => [[1, 2, 3], [1, 0, 0]]
a.sort => [[1, 0, 0], [1, 2, 3]]
a.sort_by {|x| x.first} => [[1, 2, 3], [1, 0, 0]]
a.sort {|x,y| x.first <=> y.first}
=> [[1, 2, 3], [1, 0, 0]]

Kind regards

robert
 
J

James Edward Gray II

Martin said:
pete boardman said:
On 10 Oct 2005, at 22:53, James Edward Gray II wrote:


arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2,
2.1, 4.2}}".tr("{}", "[]")
arr.sort { |a, b| a.first <=> b.first }


Thanks, James - simple, elegant, and nearly perfect! Is it easy to
sort the array of arrays by their second, third, and fourth entries
as well:

That's actually the default behaviour, so you can just say arr.sort

Strictly speaking that's wrong: the code above and arr.sort are not
equivalent because arr.sort will evaluate all elements of embedded
arrays
while the code above will only honor the first one:

I showed how to do just the first, then Pete said:

Making Martin's answer right on.

James Edward Gray II
 
R

Robert Klemme

James said:
Martin said:
On 10 Oct 2005, at 22:53, James Edward Gray II wrote:


arr = eval "{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4,
2.2,
2.1, 4.2}}".tr("{}", "[]")
arr.sort { |a, b| a.first <=> b.first }


Thanks, James - simple, elegant, and nearly perfect! Is it easy to
sort the array of arrays by their second, third, and fourth entries
as well:


That's actually the default behaviour, so you can just say arr.sort

Strictly speaking that's wrong: the code above and arr.sort are not
equivalent because arr.sort will evaluate all elements of embedded
arrays
while the code above will only honor the first one:

I showed how to do just the first, then Pete said:

Making Martin's answer right on.

Erm, yes. My fault! Apparently I'm not able to read news properly any
more - I should go home now.

Sorry for the noise

robert
 
E

ES

pete said:
One more thing - I forgot that I need to get the result back to a
string... So (thanks to your help andn Ruby's 'eval') I can go from this:

"{{3.1, 1.3, 2.5, 2.1}, {2.1, 3.1, 2.4, 2.2}, {1.4, 2.2, 2.1, 4.2}}"

to this:

[[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]

but I can't persuade the 'p' method to turn this back into a string:

Kernel#p actually prints stuff, using #inspect rather than #to_s. So,
my_array.inspect will give you the below String.
"[[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]"

(and I should be able to go from here to :

"{{1.4, 2.2, 2.1, 4.2}, {2.1, 3.1, 2.4, 2.2}, {3.1, 1.3, 2.5, 2.1}}"

on my own :)

Yep, just do the exact inverse of how you got the normal Array syntax.
Why do you need to translate it back to the same form, though?

E
 
P

pete boardman

Kernel#p actually prints stuff, using #inspect rather than #to_s. So,
my_array.inspect will give you the below String.

Right, so I can get access to the form shown by 'p'. Great!
"[[1.4, 2.2, 2.1, 4.2], [2.1, 3.1, 2.4, 2.2], [3.1, 1.3, 2.5, 2.1]]"
(and I should be able to go from here to :
"{{1.4, 2.2, 2.1, 4.2}, {2.1, 3.1, 2.4, 2.2}, {3.1, 1.3, 2.5, 2.1}}"
on my own :)

Yep, just do the exact inverse of how you got the normal Array syntax.
Why do you need to translate it back to the same form, though?

I was hoping that nobody was going to ask :). Oh well: the curly
bracket format is AppleScript's list notation, and information is
often passed around in AppleScript using lists and lists of lists.
However, AppleScript lists are not very powerful (and there are
hardly any built-in methods). This trick of passing a string version
of a list to Ruby and making use of Ruby's more powerful methods
works nicely once I learned how to get the information back from Ruby
to AppleScript in list form.

thanks again all

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top