tricky sort for happy visitors of Paris

J

Josselin

all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2' ,
'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

which seems betetr in a list... ;-))

thanks for your light

joss
 
D

dblack

Hi --

all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2' ,
'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' , 'Paris
11' , ..... 'Paris 19' , 'Paris 20' ]

which seems betetr in a list... ;-))

You could do:

arronds.sort_by {|a| a[/\d+/].to_i }

That will grab the digits, convert them to an integer, and sort based
on that.


David

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
R

Rob Biedenharn

all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris
2' , 'Paris 20' , 'Paris 3' , .... 'Paris 9' ]
paris = (1..20).map {|i| "Paris #{i}"}.sort
=> ["Paris 1", "Paris 10", "Paris 11", "Paris 12", "Paris 13", "Paris
14", "Paris 15", "Paris 16", "Paris 17", "Paris 18", "Paris 19",
"Paris 2", "Paris 20", "Paris 3", "Paris 4", "Paris 5", "Paris 6",
"Paris 7", "Paris 8", "Paris 9"]
is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

which seems betetr in a list... ;-))

thanks for your light

joss
paris.sort_by { |division| division.match(/(\d+)/)[1].to_i }
=> ["Paris 1", "Paris 2", "Paris 3", "Paris 4", "Paris 5", "Paris 6",
"Paris 7", "Paris 8", "Paris 9", "Paris 10", "Paris 11", "Paris 12",
"Paris 13", "Paris 14", "Paris 15", "Paris 16", "Paris 17", "Paris
18", "Paris 19", "Paris 20"]

if you have other cities or more than one embedded number, this is
likely too simple, but it works for your example.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
N

Nicolas Desprès

all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2' ,
'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

Somethings like (I've not tested the code):

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ].sort do |a, b|
re =3D /\s(\d+)$/
re.match(a)
ai =3D $1.to_i
re.match(b)
bi =3D $1.to_i
ai <=3D> bi
end

Cheers

--=20
Nicolas Despr=E8s
 
F

Farrel Lifson

all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2' ,
'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

which seems betetr in a list... ;-))

thanks for your light

joss

["Paris 1","Paris 10","Paris 2"].sort_by{|a| a.split[1].to_i}

Farrel
 
J

Jamey Cribbs

Josselin said:
all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2'
, 'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

arrondissement_arr.sort_by { |a| a.split.last.to_i }


Jamey

Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient(s), you are hereby notified that any dissemination, unauthorized review, use, disclosure or distribution of this email and any materials contained in any attachments is prohibited. If you receive this message in error, or are not the intended recipient(s), please immediately notify the sender by email and destroy all copies of the original message, including attachments.
 
U

Uma Geller

which seems betetr in a list... ;-))


arrondissements = ["Paris 1", "Paris 2","Paris 4", "Paris 3"]
sorted_array = arrondissements.sort_by {|e| e.split(" ")[1].to_i }
 
P

Peter Hickman

This is just begging for a natural sort order method for the array
class. Has anyone created one yet?
 
U

Uma Geller

arrondissement_arr.sort_by { |a| a.split.last.to_i }

your arys are better than myne ! :)

thanks for the tip
 
J

johan556

On 12/20/06 said:
['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2' ,
'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

which seems betetr in a list... ;-))

I have had a similar problem several times (but not with Paris :), and
I wrote a general utility function like this:

def sort_numbers_numerically(arr)
arr.sort_by do |str|
i = 0
str.split(/(\d+)/).map do |part|
i += 1
i % 2 == 0 ? part.to_i : part
end
end
end

It is of course very similar to the previously proposed solutions, but
is more general in that it sorts strings with several numbers in them,
treating each number "numerically" (one extreme example could be
IP-numbers).

/johan
 
J

Josselin

all happy visitors of Paris know about the 'arrondissement', an
administrative division of the city... 20 divisions

selecting them from a city table I can map them as :

['Paris 1' , 'Paris 10' , 'Paris 11' , ..... 'Paris 19' , 'Paris 2' ,
'Paris 20' , 'Paris 3' , .... 'Paris 9' ]

is there any way to sort this array and get :

['Paris 1' , 'Paris 2' , 'Paris 3' , .... 'Paris 9' , 'Paris 10' ,
'Paris 11' , ..... 'Paris 19' , 'Paris 20' ]

which seems betetr in a list... ;-))

thanks for your light

joss

Thanks to all of you.... cannot invite you for a Xmas drink on the
Champs-Elysees but cheers...
(whatever I am not living in Paris.... but in the Celtic land.... the
French Far West....
 
D

Devin Mullins

It is of course very similar to the previously proposed solutions, but
is more general in that it sorts strings with several numbers in them,
treating each number "numerically" (one extreme example could be
IP-numbers).
What about this?
arr.sort_by {|s| s.scan(/\d+/).map {|n| n.to_i } }

Devin
 
J

Jos Backus

More generally:

lizzy:~% irb
irb(main):001:0> arrondissements = ["Paris 1", "Paris 2","Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
=> ["Paris 1", "Paris 2", "Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
irb(main):002:0> sorted_array = arrondissements.sort_by {|e| [e.split(" ")]}
=> ["Lyon 1", "Lyon 2", "Paris 1", "Paris 2", "Paris 3", "Paris 4"]
irb(main):003:0> % lizzy:~%
 
W

William James

Jos said:
More generally:

lizzy:~% irb
irb(main):001:0> arrondissements = ["Paris 1", "Paris 2","Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
=> ["Paris 1", "Paris 2", "Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
irb(main):002:0> sorted_array = arrondissements.sort_by {|e| [e.split(" ")]}
=> ["Lyon 1", "Lyon 2", "Paris 1", "Paris 2", "Paris 3", "Paris 4"]
irb(main):003:0> % lizzy:~%

Won't work for

arrondissements = "Paris 1", "Paris 2","Paris 12", "Paris 3",
"Lyon 2", "Lyon 1"

For the 2nd field, you need a numeric comparison.

p arrondissements.sort_by {|e| e.split.inject{|a,b| [a,b.to_i] } }
 
D

dblack

Hi --

Jos said:
More generally:

lizzy:~% irb
irb(main):001:0> arrondissements = ["Paris 1", "Paris 2","Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
=> ["Paris 1", "Paris 2", "Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
irb(main):002:0> sorted_array = arrondissements.sort_by {|e| [e.split(" ")]}
=> ["Lyon 1", "Lyon 2", "Paris 1", "Paris 2", "Paris 3", "Paris 4"]
irb(main):003:0> % lizzy:~%

Won't work for

arrondissements = "Paris 1", "Paris 2","Paris 12", "Paris 3",
"Lyon 2", "Lyon 1"

For the 2nd field, you need a numeric comparison.

p arrondissements.sort_by {|e| e.split.inject{|a,b| [a,b.to_i] } }

Or:

require 'scanf'
p @arrondissements.sort_by {|e| e.scanf("%s%d") }


David

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
J

Jos Backus

Jos said:
More generally:

lizzy:~% irb
irb(main):001:0> arrondissements = ["Paris 1", "Paris 2","Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
=> ["Paris 1", "Paris 2", "Paris 4", "Paris 3", "Lyon 2", "Lyon 1"]
irb(main):002:0> sorted_array = arrondissements.sort_by {|e| [e.split(" ")]}
=> ["Lyon 1", "Lyon 2", "Paris 1", "Paris 2", "Paris 3", "Paris 4"]
irb(main):003:0> % lizzy:~%

Won't work for

arrondissements = "Paris 1", "Paris 2","Paris 12", "Paris 3",
"Lyon 2", "Lyon 1"

For the 2nd field, you need a numeric comparison.

p arrondissements.sort_by {|e| e.split.inject{|a,b| [a,b.to_i] } }

Oops, you're right, I missed that. Clever use of inject, by the way.
 
P

Père Noël

Josselin said:
whatever I am not living in Paris.... but in the Celtic land.... the
French Far West....

Then, u're living with an unefficient(*) umbrella over the head ???

* unefficient because in france "little britany" their is too much wing
to let you open your umbrella ;-)
 
J

johan556

What about this?
arr.sort_by {|s| s.scan(/\d+/).map {|n| n.to_i } }

My example with IP-numbers was perhaps an ill-chosen one. I just
wanted to indicate that my solution could handle several numbers in
the string.

It also considers the string parts as significant. Suppose the input
is like this:

arr = [
"Paris 1", "Paris 5", "Paris 14",
"Lyon 2", "Lyon 6", "Lyon 15",
]

Your code will give:

["Paris 1", "Lyon 2", "Paris 5", "Lyon 6", "Paris 14", "Lyon 15"]

and my code gives:

["Lyon 2", "Lyon 6", "Lyon 15", "Paris 1", "Paris 5", "Paris 14"]

I guess the code one would choose depends on exactly what one wants to
accomplish. In the general case it may be important to consider the
string parts too (e.g. "Paris" and "Lyon") and not just look at the
numbers.

/johan
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top