-
-
Save jmeirow/4153347 to your computer and use it in GitHub Desktop.
create array of ranges from array of individual values
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Array | |
def to_range | |
highs = self.select { |x| !self.include?(x+1) }.sort_by { |x| x } | |
lows = self.select { |x| !self.include?(x-1) }.sort_by { |x| x } | |
lows.zip(highs).map { |a,b| a..b } | |
end | |
end | |
# Running tests: | |
#................ | |
#Finished tests in 0.004272s, 3745.3184 tests/s, 9363.2959 assertions/s. | |
#16 tests, 40 assertions, 0 failures, 0 errors, 0 skips |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'minitest/spec' | |
require 'minitest/autorun' | |
require_relative 'to_range' | |
describe '#to_range' do | |
describe "empty set" do | |
it "should return an empty set" do | |
[].to_range.count.must_equal 0 | |
end | |
end | |
describe "one item" do | |
[1, 2, 1001].each do |value| | |
it "should return one range" do | |
result = [value].to_range | |
result.count.must_equal 1 | |
result[0].must_equal value..value | |
end | |
end | |
end | |
describe "two consecutive items" do | |
[[1,2], [3,4], [10000, 10001]].each do |array| | |
it "should return one range" do | |
result = [array[0],array[1]].to_range | |
result.count.must_equal 1 | |
result[0].must_equal array[0]..array[1] | |
end | |
end | |
end | |
describe "two nonconsecutive items" do | |
[[1,3], [3, 5], [566, 1001]].each do |array| | |
it "should return two ranges for each item" do | |
result = array.to_range | |
result.count.must_equal 2 | |
result[0].must_equal array[0]..array[0] | |
result[1].must_equal array[1]..array[1] | |
end | |
end | |
end | |
describe "three consecutive items" do | |
[[1,2,3], [2,3,4], [100,101,102]].each do |array| | |
it "should return one range" do | |
result = array.to_range | |
result.count.must_equal 1 | |
result[0].must_equal array.first..array.last | |
end | |
end | |
end | |
describe "joe's example" do | |
it "should return one range" do | |
result = [1,2,3,4,5,100,101,102,400,401,402,403,404,405,406].to_range | |
result.count.must_equal 3 | |
result[0].must_equal 1..5 | |
result[1].must_equal 100..102 | |
result[2].must_equal 400..406 | |
end | |
end | |
describe "unordered example" do | |
it "should return one range" do | |
result = [4,3,100,102,1000,1,2,101].to_range | |
result.count.must_equal 3 | |
result[0].must_equal 1..4 | |
result[1].must_equal 100..102 | |
result[2].must_equal 1000..1000 | |
end | |
end | |
describe "with dates" do | |
it "should return ranges just like with integers" do | |
result = ['2012-11-26', '2012-11-27', '2012-11-28', '2013-01-01', '2013-01-02', '2013-01-04']. | |
map { |x| Date.parse(x) }.to_range | |
result.count.must_equal 3 | |
result[0].must_equal Date.parse('2012-11-26')..Date.parse('2012-11-28') | |
result[1].must_equal Date.parse('2013-01-01')..Date.parse('2013-01-02') | |
result[2].must_equal Date.parse('2013-01-04')..Date.parse('2013-01-04') | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment