多重配列の複数オーダーソート
ついでなんで。
Generator なんて初めて使いまった。Generator っていうより Iterator だよね。
#!/usr/bin/ruby require 'generator' class Symbol def <=> b self.to_s <=> b.to_s end end def rcmp(a, b, i) c = i.current if a[c] == b[c] && i.next? i.next return rcmp(a, b, i) else i.rewind return a[c] <=> b[c] end end class Array def order_by(*order) return nil unless order if order.size == 1 return self.sort_by{|e| e[order[0]]} else i = Generator.new(order) return self.sort { |a,b| rcmp(a, b, i) } end end end m_ary = [ ["a", 5], ["b", 4], ["a", 3], ["c", 2], ["a", 1], ] if __FILE__ == $0 puts "ORDER BY 1:" m_ary.order_by(1).each do |e| puts "\t" + e.inspect end puts "ORDER BY 0,1:" m_ary.order_by(0, 1).each do |e| puts "\t" + e.inspect end puts "ORDER BY 0 but Symbol" m_ary.map{|e| [e[0].to_sym, e[1]]}.order_by(0).each do |e| puts "\t" + e.inspect end end
わざわざ作らないでも Math にありそう、もしくは、ググれば落ちてそう。
LINQ っぽく Ruby で書く 時、順番を複数指定したい場合、カンマ区切り等で簡単に書けないよなと思って。けど、趣旨がずれてしまって、ブロック取らないし Struct や オブジェクトを要素とした配列にも対応してない。誰かやって。
あー、しまった、sort_by で配列を受け付けるように手を入れた方が良かったかぁ?