From: Dave Thomas Date: 2001-11-30T14:55:44+09:00 Subject: [ruby-talk:27029] Re: Help: factored sorting Bil Kleb writes: > I have an array of strings, > > a = ["d3", "d33", "d4", "r16", "r33", "d34", "r34"] > > which I'd like to sort by both the numerical suffix and by > the alphabetic prefix, i.e., I'd like the result, > > ["d3", "d4", "d33", "d34", "r16", "r33", "r34"] Bil: The sort part could be something like: a.map { |e| w, d = /([a-z]+)(\d+)/.match(e)[1,2] [ w, d.to_i, e] } . sort {|a,b| (a[0] <=> b[0]).nonzero? || a[1] <=> b[1] } . map {|a,b,e| e} > or, even better would be an array of two prefix-keyed > sub arrays that I could exploit with the assoc method, > viz, > > [ ["d", "d3", "d4", "d33", "d34"], ["r", "r16", "r33", "r34"] ] I'd probably do this in three phases - it's a tad ugly.. result = {} a.each { |e| w, d = /([a-z]+)(\d+)/.match(e)[1,2] (result[w] ||= []) << d.to_i } result.each_value {|v| v.sort! } result = result.to_a.sort.map { |letter,values| [ letter, values.map {|v| letter + v.to_s} ].flatten } If you're flexible in the format of the result, there's also: result = {} a.each { |e| w, d = /([a-z]+)(\d+)/.match(e)[1,2] (result[w] ||= []) << d.to_i } result.each_value {|v| v.sort! } .to_a.sort The result's not quite what you asked for: [ [ "d", [3, 4, 33, 34] ], ["r", [16, 33, 34] ] ] Regards Dave