如何对“章号”进行排序,如1.1.1,1.2.1,1.2.46等?

时间:2015-07-13 16:00:19

标签: ruby sorting

有没有快速的方法在Ruby中对“章节数”进行排序?

1.1.1
1.1.2
1.2.1
1.3.1
1.3.2
1.3.3
10.42.64
etc.?

我是否必须写一个枚举器或类似的东西?

2 个答案:

答案 0 :(得分:11)

在Ruby中,Array按字典顺序排序,因此最简单的方法是将这些转换为Array然后对它们进行排序:

chapters = %w[1.1.1 1.1.2 1.2.1 1.3.1 1.3.2 1.3.3 10.42.64]

chapters.sort_by {|chapter| chapter.split('.').map(&:to_i) }
# => ["1.1.1", "1.1.2", "1.2.1", "1.3.1", "1.3.2", "1.3.3", "10.42.64"]

当然,真正的解决方案是使用对象而不是围绕数字字符串数组。毕竟,Ruby是面向对象的语言,而不是面向数字字符串的语言:

class ChapterNumber
  include Comparable

  def initialize(*nums)
    self.nums = nums
  end

  def <=>(other)
    nums <=> other.nums
  end

  def to_s
    nums.join('.')
  end

  alias_method :inspect, :to_s

  protected

  attr_reader :nums

  private

  attr_writer :nums
end

chapters = [ChapterNumber.new(1, 1, 1), ChapterNumber.new(1, 1, 2), 
  ChapterNumber.new(1, 2, 1), ChapterNumber.new(1, 3, 1), 
  ChapterNumber.new(1, 3, 2), ChapterNumber.new(1, 3, 3), 
  ChapterNumber.new(10, 42, 64)]

chapters.sort
# => [1.1.1, 1.1.2, 1.2.1, 1.3.1, 1.3.2, 1.3.3, 10.42.64]

答案 1 :(得分:0)

(l: string, r: string) => {
    const left = l.split('.');
    const right = r.split('.');

    let count = Math.max(left.length, right.length);

    let idx = 0;

    while (idx < count) {
        const lValue = parseInt((left[idx] || '0'));
        const rValue = parseInt((right[idx] || '0'));
        if (lValue === rValue) {
            idx++
        } else {
            return lValue < rValue ? -1 : lValue > rValue ? 1 : 0;
        }
    }

    return 0;
};