Dave Thomas <Dave / PragmaticProgrammer.com> wrote: >"Wilka" <jvyxn / evghnyvfgvp.pbz> writes: > [...] >Here are a couple of ways. The second may or may not be more >efficient, as it only does the pattern match and to_i once for each >string in the array. > > strings = [ "Name 300", "Name 1", "Name 10", "Name 2" ] > > # an inefficient way (if there are large numbers of strings) > > digits = /\d+$/ > > res = strings.sort { |a, b| digits.match(a)[0].to_i <=> >digits.match(b)[0].to_i} > > # a more efficient way (perhaps) > > res = strings. > collect {|e| [ digits.match(e)[0].to_i, e ] }. > sort {|a, b| a[0] <=> b[0] }. > collect {|e| e[1]} > Note that both of these just sort the strings based on the embedded number. The Schwartzian sort example that I gave earlier pays attention to the number and works for a larger variety of strings, including (for instance) mixed text, most version number schemes, and dotted quad IP numbers correctly. (OTOH if I was in a hurry and hadn't already thought about this problem before I would have probably done something like the above as well.) BTW I made it somewhat more complex (so it will handle negative numbers, takes into account most people's preference for case-insensitive sorts, etc): def sort_split (s) # Each piece case insensitive then by number, # finally usual lexical order pieces = s.scan(/(\D*)(\d*)/) pieces.each {|elem| elem[0].downcase! elem[1] = elem[1].sub(/^0*/, '').to_i if "" != elem[0] and "-" == elem[0].slice(-1, 1) elem[0].chop! elem[1] *= -1 end } pieces.push s end things = (-5..20).to_a.map {|i| "thing #{i}"} things.push ( "thing ", "hello", "world", "This", "That", "This -", "this" ) puts things.map {|e| sort_split(e)} .sort.map {|e| e[-1]} Cheers, Ben _________________________________________________________________ Get your FREE download of MSN Explorer at http://explorer.msn.com