开发者

Sorting Section Headers in Ruby

What is a good way of sorting section number strings in Ruby. For example:

sections = ["10", "3", "4", "5", "6", "7", "8", "9", "2", "1", "1.1", "1.1.1", "1.1.2"]
# ["1", "1.1开发者_Go百科", "1.1.1", "1.1.2", "2", "3", "4", "5", "6", "7", "8", "9", "10"]


If you have to deal with arbitrarily nested subsections then you could do something like this:

sections = ["10", "3", "4", "5", "6", "7", "8", "9", "2", "1", "1.1", "1.2", "1.2.5"]
sections.sort! { |a,b| a.split('.').map(&:to_i) <=> b.split('.').map(&:to_i) }

That implementation isn't exactly quick due to the repeated split and map but you could roll your own Schwartzian Transform if it was too slow:

sections.map  { |e| [e, e.split('.').map(&:to_i) ] } \
        .sort { |a, b| a.last <=> b.last } \
        .map  { |e| e.first }

Note that Enumerable#sort_by does an internal Schwartzian Transform for you:

The current implementation of sort_by generates an array of tuples containing the original collection element and the mapped value.

So you could also let sort_by take care of some of the ugliness:

section.sort_by { |e| e.split('.').map(&:to_i) }

and get something that is pretty easy to understand at a glance.


If it is possible that you may go to more than two levels, you can do the following:

sections.sort_by{ |section| section.split('.').map(&:to_i)}


Use Enumerable's sort_by method:

sections.sort_by(&:to_f)

Or, the slightly longer version:

sections.sort_by{ |section| section.to_f }


IF they are always going to be like that you could cast them to floats..

sections = ["10", "3", "4", "5", "6", "7", "8", "9", "2", "1", "1.1", "1.2"]
    => ["10", "3", "4", "5", "6", "7", "8", "9", "2", "1", "1.1", "1.2"]

sections.sort {|x,y| x.to_f <=> y.to_f}
=> ["1", "1.1", "1.2", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜