Implement Utils.sort_tuples! for user-defined sorting

This commit is contained in:
Akinori MUSHA 2015-07-02 15:27:22 +09:00
parent 66e72eff75
commit 06554eaf31
2 changed files with 80 additions and 0 deletions

View file

@ -79,4 +79,44 @@ module Utils
def self.pretty_jsonify(thing)
JSON.pretty_generate(thing).gsub('</', '<\/')
end
class TupleSorter
class SortableTuple
attr_reader :array
# The <=> method will call orders[n] to determine if the nth element
# should be compared in descending order.
def initialize(array, orders = [])
@array = array
@orders = orders
end
def <=> other
other = other.array
@array.each_with_index do |e, i|
case cmp = e <=> other[i]
when nil
return nil
when 0
next
else
return @orders[i] ? -cmp : cmp
end
end
0
end
end
class << self
def sort!(array, orders = [])
array.sort_by! do |e|
SortableTuple.new(e, orders)
end
end
end
end
def self.sort_tuples!(array, orders = [])
TupleSorter.sort!(array, orders)
end
end

View file

@ -114,4 +114,44 @@ describe Utils do
expect(cleaned_json).to include("<\\/script>")
end
end
describe "#sort_tuples!" do
let(:tuples) {
time = Time.now
[
[2, "a", time - 1], # 0
[2, "b", time - 1], # 1
[1, "b", time - 1], # 2
[1, "b", time], # 3
[1, "a", time], # 4
[2, "a", time + 1], # 5
[2, "a", time], # 6
]
}
it "sorts tuples like arrays by default" do
expected = tuples.values_at(4, 2, 3, 0, 6, 5, 1)
Utils.sort_tuples!(tuples)
expect(tuples).to eq expected
end
it "sorts tuples in order specified: case 1" do
# order by x1 asc, x2 desc, c3 asc
orders = [false, true, false]
expected = tuples.values_at(2, 3, 4, 1, 0, 6, 5)
Utils.sort_tuples!(tuples, orders)
expect(tuples).to eq expected
end
it "sorts tuples in order specified: case 2" do
# order by x1 desc, x2 asc, c3 desc
orders = [true, false, true]
expected = tuples.values_at(5, 6, 0, 1, 4, 3, 2)
Utils.sort_tuples!(tuples, orders)
expect(tuples).to eq expected
end
end
end