From 06554eaf31ea2e5edc54f995130091a0adcf3bdf Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Thu, 2 Jul 2015 15:27:22 +0900 Subject: [PATCH] Implement Utils.sort_tuples! for user-defined sorting --- lib/utils.rb | 40 ++++++++++++++++++++++++++++++++++++++++ spec/lib/utils_spec.rb | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/lib/utils.rb b/lib/utils.rb index a5800283..4a8ad396 100644 --- a/lib/utils.rb +++ b/lib/utils.rb @@ -79,4 +79,44 @@ module Utils def self.pretty_jsonify(thing) JSON.pretty_generate(thing).gsub(' 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 diff --git a/spec/lib/utils_spec.rb b/spec/lib/utils_spec.rb index 7f9baaeb..26125771 100644 --- a/spec/lib/utils_spec.rb +++ b/spec/lib/utils_spec.rb @@ -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