range_operators 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/Manifest +4 -2
- data/README.rdoc +30 -6
- data/Rakefile +2 -2
- data/lib/range_operators.rb +2 -47
- data/lib/range_operators/array_operator_definitions.rb +92 -0
- data/lib/range_operators/range_operator_definitions.rb +48 -0
- data/range_operators.gemspec +6 -6
- data/spec/array_operator_definitions_spec.rb +63 -0
- data/spec/range_operators_spec.rb +69 -146
- metadata +11 -8
- metadata.gz.sig +0 -0
- data/lib/rangify.rb +0 -52
data.tar.gz.sig
CHANGED
Binary file
|
data/Manifest
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
LICENSE
|
2
|
-
Manifest
|
3
2
|
README.rdoc
|
4
3
|
Rakefile
|
5
4
|
lib/range_operators.rb
|
6
|
-
lib/
|
5
|
+
lib/range_operators/array_operator_definitions.rb
|
6
|
+
lib/range_operators/range_operator_definitions.rb
|
7
|
+
spec/array_operator_definitions_spec.rb
|
7
8
|
spec/range_operators_spec.rb
|
9
|
+
Manifest
|
data/README.rdoc
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
= RangeOperators
|
2
2
|
|
3
|
-
This gem will mixin range operations
|
3
|
+
This gem will mixin range operations into Ruby's Range and Array classes.
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
Range Methods:: Addition and subtraction
|
6
|
+
|
7
|
+
Array Methods:: Combining elements into ranges, determining intersection of elements,
|
8
|
+
and determining missing elements
|
7
9
|
|
8
10
|
It assumes inclusive ranges (ie. 1..4) and range.first <= range.last.
|
9
|
-
|
10
|
-
Values returned from the operations are in an array.
|
11
|
+
Also, the objects making up the ranges must have #succ and #<=> methods.
|
11
12
|
|
12
13
|
= Usage
|
13
14
|
|
14
|
-
The methods added are Range#- (alias Range#minus)
|
15
|
+
The methods added are Range#- (alias Range#minus), Range#+ (alias Range#plus), Array#rangify, Array#intersection, and Array#missing.
|
15
16
|
|
16
17
|
|
17
18
|
Examples:
|
@@ -22,6 +23,29 @@ irb > (1..10) - (4..6) => [1..3, 7..10]
|
|
22
23
|
|
23
24
|
irb > (1..10).minus(9..12) => [1..8]
|
24
25
|
|
26
|
+
Note: #- requires that the second operand have a #- (integer) method defined (ie. Fixnum, Bignum, and Date).
|
27
|
+
(This allows the determination of a previous/predecessor value of an object.)
|
28
|
+
----
|
29
|
+
|
25
30
|
irb > (1..10) + (9..12) => [1..12]
|
26
31
|
|
27
32
|
irb > (1..10).plus(15..20) => [1..10, 15..20]
|
33
|
+
----
|
34
|
+
|
35
|
+
irb > [1,2,3,6,7,8].rangify => [1..3, 6..8]
|
36
|
+
|
37
|
+
irb > [10..15, 16..20, 21, 22].rangify => [10..22]
|
38
|
+
----
|
39
|
+
|
40
|
+
irb > [1, 2].intersection => nil
|
41
|
+
|
42
|
+
irb > [1..10, 1].intersection => 1
|
43
|
+
|
44
|
+
irb > [5..10, 1..10, 4..8 ].intersection => 5..8
|
45
|
+
|
46
|
+
Note: #intersection will determine the values in common to all of the elements.
|
47
|
+
----
|
48
|
+
|
49
|
+
irb > [100, 9..11, 14, 1..5, 16, 10..12, 17..17].missing => [6..8, 13, 15, 18..99]
|
50
|
+
|
51
|
+
Note: Like #-, #missing requires that the second operand have a #- (integer) method.
|
data/Rakefile
CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('range_operators', '0.
|
6
|
-
p.description = "A gem that adds
|
5
|
+
Echoe.new('range_operators', '0.1.1') do |p|
|
6
|
+
p.description = "A gem that adds range methods to Ruby's Range and Array classes. (Range#+, Range#-, Array#rangify, Array#intersection, Array#missing)"
|
7
7
|
p.url = "http://github.com/monocle/range_operators"
|
8
8
|
p.author = "monocle"
|
9
9
|
p.email = "frappez_2000@yahoo.com"
|
data/lib/range_operators.rb
CHANGED
@@ -1,47 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
#Assumes inclusive ranges (ie. 1..4) and range.first <= range.last.
|
4
|
-
#Values returned from the operations are in an array.
|
5
|
-
module RangeOperators
|
6
|
-
require 'rangify'
|
7
|
-
|
8
|
-
def +(value)
|
9
|
-
[self, value].rangify
|
10
|
-
end
|
11
|
-
|
12
|
-
alias plus +
|
13
|
-
|
14
|
-
def -(value)
|
15
|
-
if value.class == self.first.class
|
16
|
-
self.minus_obj(value)
|
17
|
-
else
|
18
|
-
[self.minus_obj(value.first)[0], self.minus_obj(value.last)[1]].compact
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
alias minus -
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
def minus_obj(value)
|
27
|
-
first = case value <=> self.first.succ
|
28
|
-
when -1 then nil
|
29
|
-
when 0 then self.first
|
30
|
-
else
|
31
|
-
value < self.last.succ ? self.first..(value - 1) : self
|
32
|
-
end
|
33
|
-
|
34
|
-
second = case self.last <=> value.succ
|
35
|
-
when -1 then nil
|
36
|
-
when 0 then self.last
|
37
|
-
else
|
38
|
-
value.succ > self.first ? value.succ..self.last : self
|
39
|
-
end
|
40
|
-
|
41
|
-
[first, second]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Range
|
46
|
-
include RangeOperators
|
47
|
-
end
|
1
|
+
require 'range_operators/array_operator_definitions'
|
2
|
+
require 'range_operators/range_operator_definitions'
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module RangeOperators
|
2
|
+
#= Rangify
|
3
|
+
#
|
4
|
+
#This module will add the rangify method to Ruby's Array class.
|
5
|
+
#The rangify method will produce appropriate ranges from the objects in the array.
|
6
|
+
#
|
7
|
+
#= Usage
|
8
|
+
#
|
9
|
+
#Examples:
|
10
|
+
#
|
11
|
+
#[1,2,3,6,7,8].rangify = [1..3, 6..8]
|
12
|
+
#
|
13
|
+
#[10..15, 16..20, 21, 22].rangify = [10..22]
|
14
|
+
#
|
15
|
+
#
|
16
|
+
#Assumes inclusive ranges (ie. 1..4) and range.first <= range.last.
|
17
|
+
#
|
18
|
+
#Works with integers, dates and strings. However, all the objects in the array must be of the same class.
|
19
|
+
module ArrayOperatorDefinitions
|
20
|
+
def rangify
|
21
|
+
array = self.sort_elements
|
22
|
+
array.inject([]) do |collection, value|
|
23
|
+
unless collection.empty?
|
24
|
+
last = collection.last
|
25
|
+
last_value = comparison_value(last, :last)
|
26
|
+
current_value = comparison_value(value, :first)
|
27
|
+
if (last_value.succ <=> current_value) == -1
|
28
|
+
collection << value
|
29
|
+
else
|
30
|
+
first = comparison_value(last, :first)
|
31
|
+
second = [comparison_value(last, :last), comparison_value(value, :last)].max
|
32
|
+
collection[-1] = [first..second]
|
33
|
+
collection.flatten!
|
34
|
+
end
|
35
|
+
else
|
36
|
+
collection << value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the values in common for an array set (nil, singe value/object, or range).
|
42
|
+
def intersection
|
43
|
+
array = self.sort_elements
|
44
|
+
array.inject() do |common, element|
|
45
|
+
value_first = comparison_value(common, :last)
|
46
|
+
value_element = comparison_value(element, :first)
|
47
|
+
case value_first <=> value_element
|
48
|
+
when -1 then return nil
|
49
|
+
when 0 then value_first
|
50
|
+
else
|
51
|
+
if element.class == Range
|
52
|
+
value_element..([value_first, comparison_value(element, :last)].min)
|
53
|
+
else
|
54
|
+
value_element
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#Returns the missing elements in an array set
|
61
|
+
def missing
|
62
|
+
missing, array = [], self.rangify
|
63
|
+
i, length = 0, array.size - 1
|
64
|
+
|
65
|
+
while i < length
|
66
|
+
current = comparison_value(array[i], :last)
|
67
|
+
nextt = comparison_value(array[i+1], :first)
|
68
|
+
missing << (current.succ.succ == nextt ? current.succ : (current.succ)..(nextt - 1))
|
69
|
+
i += 1
|
70
|
+
end
|
71
|
+
missing
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def sort_elements
|
77
|
+
self.uniq.sort_by { |element| comparison_value(element, :first) }
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# For a Range, will return value.first or value.last. A non-Range will return itself.
|
83
|
+
def comparison_value(value, position)
|
84
|
+
return value if value.class != Range
|
85
|
+
position == :first ? value.first : value.last
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Array
|
91
|
+
include RangeOperators::ArrayOperatorDefinitions
|
92
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RangeOperators
|
2
|
+
#Will add range operations ('+' and '-') to Ruby's Range class.
|
3
|
+
#Requires that the second operand have a '- (integer)' method defined (ie. Fixnum, Bignum, and Date).
|
4
|
+
#Assumes inclusive ranges (ie. 1..4) and range.first <= range.last.
|
5
|
+
#Values returned from the operations are in an array.
|
6
|
+
module RangeOperatorDefinitions
|
7
|
+
|
8
|
+
def +(value)
|
9
|
+
[self, value].rangify
|
10
|
+
end
|
11
|
+
|
12
|
+
alias plus +
|
13
|
+
|
14
|
+
def -(value)
|
15
|
+
if value.class == self.first.class
|
16
|
+
self.minus_obj(value)
|
17
|
+
else
|
18
|
+
[self.minus_obj(value.first)[0], self.minus_obj(value.last)[1]].compact
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
alias minus -
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def minus_obj(value)
|
27
|
+
first = case value <=> self.first.succ
|
28
|
+
when -1 then nil
|
29
|
+
when 0 then self.first
|
30
|
+
else
|
31
|
+
value < self.last.succ ? self.first..(value - 1) : self
|
32
|
+
end
|
33
|
+
|
34
|
+
second = case self.last <=> value.succ
|
35
|
+
when -1 then nil
|
36
|
+
when 0 then self.last
|
37
|
+
else
|
38
|
+
value.succ > self.first ? value.succ..self.last : self
|
39
|
+
end
|
40
|
+
|
41
|
+
[first, second]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Range
|
47
|
+
include RangeOperators::RangeOperatorDefinitions
|
48
|
+
end
|
data/range_operators.gemspec
CHANGED
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{range_operators}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.1.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["monocle"]
|
9
9
|
s.cert_chain = ["/ruby/keys/range_operators/gem-public_cert.pem"]
|
10
|
-
s.date = %q{2010-07-
|
11
|
-
s.description = %q{A gem that adds
|
10
|
+
s.date = %q{2010-07-04}
|
11
|
+
s.description = %q{A gem that adds range methods to Ruby's Range and Array classes. (Range#+, Range#-, Array#rangify, Array#intersection, Array#missing)}
|
12
12
|
s.email = %q{frappez_2000@yahoo.com}
|
13
|
-
s.extra_rdoc_files = ["LICENSE", "README.rdoc", "lib/range_operators.rb", "lib/
|
14
|
-
s.files = ["LICENSE", "
|
13
|
+
s.extra_rdoc_files = ["LICENSE", "README.rdoc", "lib/range_operators.rb", "lib/range_operators/array_operator_definitions.rb", "lib/range_operators/range_operator_definitions.rb"]
|
14
|
+
s.files = ["LICENSE", "README.rdoc", "Rakefile", "lib/range_operators.rb", "lib/range_operators/array_operator_definitions.rb", "lib/range_operators/range_operator_definitions.rb", "spec/array_operator_definitions_spec.rb", "spec/range_operators_spec.rb", "Manifest", "range_operators.gemspec"]
|
15
15
|
s.homepage = %q{http://github.com/monocle/range_operators}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Range_operators", "--main", "README.rdoc"]
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.rubyforge_project = %q{range_operators}
|
19
19
|
s.rubygems_version = %q{1.3.6}
|
20
20
|
s.signing_key = %q{/ruby/keys/range_operators/gem-private_key.pem}
|
21
|
-
s.summary = %q{A gem that adds
|
21
|
+
s.summary = %q{A gem that adds range methods to Ruby's Range and Array classes. (Range#+, Range#-, Array#rangify, Array#intersection, Array#missing)}
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'lib/range_operators'
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
describe '#missing' do
|
5
|
+
it { [1,3..3].missing.should == [2] }
|
6
|
+
it { [1..5,10..12].missing.should == [6..9] }
|
7
|
+
it { [100, 9..11, 14, 1..5, 16, 10..12, 17..17].missing.should == [6..8, 13, 15, 18..99] }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#intersection' do
|
11
|
+
it { [1, 2].intersection.should == nil }
|
12
|
+
it { [1..10, 11..20].intersection.should == nil }
|
13
|
+
it { [1..10, 5..15, 11..20].intersection.should == nil }
|
14
|
+
it { [8..8, 1..10, 10 ].intersection.should == nil }
|
15
|
+
it { [10, 1..10].intersection.should == 10 }
|
16
|
+
it { [1..10, 1].intersection.should == 1 }
|
17
|
+
it { [1, 1].intersection.should == 1 }
|
18
|
+
it { [1..10, 5, 5..8, 5..10 ].intersection.should == 5 }
|
19
|
+
it { [1..10, 5..8, 5..10 ].intersection.should == (5..8) }
|
20
|
+
it { [5..10, 1..10, 4..8 ].intersection.should == (5..8) }
|
21
|
+
it { [5..10, 1..10, 4..20, 8].intersection.should == 8 }
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#rangify' do
|
26
|
+
|
27
|
+
it 'An array of consecutive integers should return an array made up of a single range.' do
|
28
|
+
[1,2,3,4,5].rangify.should == [1..5]
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'An array of non-consecutive integers should return the original array.' do
|
32
|
+
[1,3,5,7].rangify.should == [1,3,5,7]
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'An array of consecutive and non-consecutive integers' do
|
36
|
+
before :each do
|
37
|
+
@result = [1..3, 6..8, 10, 15]
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return the correct ranges.' do
|
41
|
+
[1,2,3,6,7,8,10,15].rangify.should == @result
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'Array element order should not affect the result.' do
|
45
|
+
[8, 1, 15, 2, 6, 3, 7, 10].rangify.should == @result
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'Duplicate elements should not affect the result.' do
|
49
|
+
[8, 1, 15, 2, 6, 3, 7, 10, 8, 15, 2, 3, 1, 2].rangify.should == @result
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'An array of ranges should return the correct ranges.' do
|
54
|
+
arr = [40..45, 1..3, 4..10, 20..30, 24..28, 42..50, 1..6, 1..3, 1..1]
|
55
|
+
arr.rangify.should == [1..10, 20..30, 40..50]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'An array of ranges and integers should return the correct ranges.' do
|
59
|
+
arr = [99, 100, 1..3, 101, 4..5, 103, 10..19, 99, 20..20, 31, 32..33, 98, 97]
|
60
|
+
arr.rangify.should == [1..5, 10..20, 31..33, 97..101, 103]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -1,180 +1,103 @@
|
|
1
1
|
require 'lib/range_operators'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Range do
|
4
4
|
describe '#+' do
|
5
5
|
describe 'when given a range of integers' do
|
6
|
-
before :each do
|
7
|
-
@range = 1..10
|
8
|
-
end
|
9
|
-
|
10
|
-
it '1..10 + 11 = [1..11]' do
|
11
|
-
(@range + 11).should == [1..11]
|
12
|
-
end
|
13
6
|
|
14
|
-
it
|
15
|
-
(@range + 12).should == [1..10, 12]
|
16
|
-
end
|
17
|
-
|
18
|
-
it '1..10 + 10..12 = [1..12]' do
|
19
|
-
(@range + (10..12)).should == [1..12]
|
20
|
-
end
|
21
|
-
|
22
|
-
it '1..10 + 11..12 = [1..12]' do
|
23
|
-
(@range + (11..12)).should == [1..12]
|
24
|
-
end
|
25
|
-
|
26
|
-
it '1..10 + 9..12 = [1..12]' do
|
27
|
-
(@range + (9..12)).should == [1..12]
|
28
|
-
end
|
29
|
-
|
30
|
-
it '1..10 + 1..12 = [1..12]' do
|
31
|
-
(@range + (1..12)).should == [1..12]
|
32
|
-
end
|
7
|
+
it { lambda{ (1..10) + 'a' }.should raise_error }
|
33
8
|
|
34
|
-
it
|
35
|
-
|
36
|
-
|
9
|
+
it { ((1..10) + (11..11)).should == [1..11] }
|
10
|
+
|
11
|
+
it { ((1..10) + 12).should == [1..10, 12] }
|
37
12
|
|
38
|
-
it
|
39
|
-
(@range + 0).should == [0..10]
|
40
|
-
end
|
13
|
+
it { ((1..10) + (10..12)).should == [1..12] }
|
41
14
|
|
42
|
-
it
|
43
|
-
(@range + -1).should == [-1, 1..10]
|
44
|
-
end
|
15
|
+
it { ((1..10) + (11..12)).should == [1..12] }
|
45
16
|
|
46
|
-
it
|
47
|
-
(@range + (-10..-1)).should == [-10..-1, 1..10]
|
48
|
-
end
|
17
|
+
it { ((1..10) + (9..12)).should == [1..12] }
|
49
18
|
|
50
|
-
it
|
51
|
-
|
52
|
-
|
19
|
+
it { ((1..10) + (1..12)).should == [1..12] }
|
20
|
+
|
21
|
+
it { ((1..10) + (12..20)).should == [1..10, 12..20] }
|
53
22
|
|
54
|
-
it
|
55
|
-
(@range + (-10..1)).should == [-10..10]
|
56
|
-
end
|
23
|
+
it { ((1..10) + 0).should == [0..10] }
|
57
24
|
|
58
|
-
it
|
59
|
-
|
60
|
-
|
25
|
+
it { ((1..10) + -1).should == [-1, 1..10] }
|
26
|
+
|
27
|
+
it { ((1..10) + (-10..-1)).should == [-10..-1, 1..10] }
|
61
28
|
|
62
|
-
it
|
63
|
-
|
64
|
-
|
29
|
+
it { ((1..10) + (-10..0)).should == [-10..10] }
|
30
|
+
|
31
|
+
it { ((1..10) + (-10..1)).should == [-10..10] }
|
32
|
+
|
33
|
+
it { ((1..10) + (-10..2)).should == [-10..10] }
|
34
|
+
|
35
|
+
it { ((1..10) + (-10..20)).should == [-10..20]}
|
65
36
|
end
|
66
37
|
end
|
67
38
|
|
68
39
|
describe '#-' do
|
69
40
|
describe 'when given a range of integers' do
|
70
|
-
before :each do
|
71
|
-
@range = 1..10
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'should raise error if subtracting a non-integer' do
|
75
|
-
lambda{@range - 'a'}.should raise_error
|
76
|
-
end
|
77
|
-
|
78
|
-
describe 'and subtracting an integer' do
|
79
|
-
it '(1..10) - 5 = [1..4, 6..10]' do
|
80
|
-
(@range - 5).should == [1..4, 6..10]
|
81
|
-
end
|
82
|
-
|
83
|
-
it '(1..10) - 2 = [1, 3..10]' do
|
84
|
-
(@range - 2).should == [1, 3..10]
|
85
|
-
end
|
86
|
-
|
87
|
-
it '(1..10)- 9 = [1..8, 10]' do
|
88
|
-
(@range - 9).should == [1..8, 10]
|
89
|
-
end
|
90
|
-
|
91
|
-
it '(1..10) - 10 = [1..9, nil]' do
|
92
|
-
(@range - 10).should == [1..9, nil]
|
93
|
-
end
|
94
|
-
|
95
|
-
it '(1..10) - 1 = [nil, 2..10]' do
|
96
|
-
(@range - 1).should == [nil, 2..10]
|
97
|
-
end
|
98
41
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
it '(1..10) - 12 = [1..10, nil]' do
|
104
|
-
(@range - 12).should == [1..10, nil]
|
105
|
-
end
|
106
|
-
|
107
|
-
it '(1..10) - 0 = [nil, 1..10]' do
|
108
|
-
(@range - 0).should == [nil, 1..10]
|
109
|
-
end
|
42
|
+
it { lambda{ (1..10) - 'a' }.should raise_error }
|
43
|
+
|
44
|
+
describe 'and subtracting an integer' do
|
110
45
|
|
111
|
-
it
|
112
|
-
|
113
|
-
|
46
|
+
it { ((1..10) - (5..5)).should == [1..4, 6..10] }
|
47
|
+
|
48
|
+
it { ((1..10) - 2).should == [1, 3..10] }
|
49
|
+
|
50
|
+
it { ((1..10) - 9).should == [1..8, 10] }
|
51
|
+
|
52
|
+
it { ((1..10) - 10).should == [1..9, nil] }
|
53
|
+
|
54
|
+
it { ((1..10) - 1).should == [nil, 2..10] }
|
55
|
+
|
56
|
+
it { ((1..10) - 11).should == [1..10, nil] }
|
57
|
+
|
58
|
+
it { ((1..10) - 12).should == [1..10, nil] }
|
59
|
+
|
60
|
+
it { ((1..10) - 0).should == [nil, 1..10] }
|
61
|
+
|
62
|
+
it { ((1..10) - -1).should == [nil, 1..10] }
|
114
63
|
end
|
115
64
|
|
116
65
|
describe 'and subtracting another range' do
|
117
66
|
|
118
|
-
it
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
it
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
it
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
it
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
it
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
it
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
it
|
143
|
-
(@range - (4..10)).should == [1..3]
|
144
|
-
end
|
145
|
-
|
146
|
-
it '1..10 - 4..12 = [1..3]' do
|
147
|
-
(@range - (4..12)).should == [1..3]
|
148
|
-
end
|
149
|
-
|
150
|
-
it '1..10 - 1..6 = [7..10]' do
|
151
|
-
(@range - (1..6)).should == [7..10]
|
152
|
-
end
|
153
|
-
|
154
|
-
it '1..10 - (-2..6) = [7..10]' do
|
155
|
-
(@range - (-2..6)).should == [7..10]
|
156
|
-
end
|
157
|
-
|
158
|
-
it '1..10 - 11..20 = [1..10]' do
|
159
|
-
(@range - (11..20)).should == [1..10]
|
160
|
-
end
|
161
|
-
|
162
|
-
it '1..10 - (-10..0) = [1..10]' do
|
163
|
-
(@range - (-10..0)).should == [1..10]
|
164
|
-
end
|
165
|
-
|
166
|
-
it '1..10 - (-10..20) = []' do
|
167
|
-
(@range - (-10..20)).should == []
|
168
|
-
end
|
67
|
+
it { ((1..10) - (4..6)).should == [1..3, 7..10] }
|
68
|
+
|
69
|
+
it { ((1..10) - (2..6)).should == [1, 7..10] }
|
70
|
+
|
71
|
+
it { ((1..10) - (4..9)).should == [1..3, 10] }
|
72
|
+
|
73
|
+
it { ((1..10) - (2..9)).should == [1, 10] }
|
74
|
+
|
75
|
+
it { ((1..10) - (2..11)).should == [1] }
|
76
|
+
|
77
|
+
it { ((1..10) - (0..9)).should == [10] }
|
78
|
+
|
79
|
+
it { ((1..10) - (4..10)).should == [1..3] }
|
80
|
+
|
81
|
+
it { ((1..10) - (4..12)).should == [1..3] }
|
82
|
+
|
83
|
+
it { ((1..10) - (1..6)).should == [7..10] }
|
84
|
+
|
85
|
+
it { ((1..10) - (-2..6)).should == [7..10] }
|
86
|
+
|
87
|
+
it { ((1..10) - (11..20)).should == [1..10] }
|
88
|
+
|
89
|
+
it { ((1..10) - (-10..0)).should == [1..10] }
|
90
|
+
|
91
|
+
it { ((1..10) - (-10..20)).should == [] }
|
169
92
|
end
|
170
93
|
end
|
171
94
|
end
|
172
95
|
|
173
96
|
it '#minus is an alias of #-' do
|
174
|
-
|
97
|
+
Range.instance_method(:minus).should == Range.instance_method(:-)
|
175
98
|
end
|
176
99
|
|
177
100
|
it '#plus is an alias of #+' do
|
178
|
-
|
101
|
+
Range.instance_method(:plus).should == Range.instance_method(:+)
|
179
102
|
end
|
180
103
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 0
|
8
7
|
- 1
|
9
|
-
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- monocle
|
@@ -35,11 +35,11 @@ cert_chain:
|
|
35
35
|
lTblHT4UBS6VZYs6PY8=
|
36
36
|
-----END CERTIFICATE-----
|
37
37
|
|
38
|
-
date: 2010-07-
|
38
|
+
date: 2010-07-04 00:00:00 -07:00
|
39
39
|
default_executable:
|
40
40
|
dependencies: []
|
41
41
|
|
42
|
-
description: A gem that adds
|
42
|
+
description: A gem that adds range methods to Ruby's Range and Array classes. (Range#+, Range#-, Array#rangify, Array#intersection, Array#missing)
|
43
43
|
email: frappez_2000@yahoo.com
|
44
44
|
executables: []
|
45
45
|
|
@@ -49,15 +49,18 @@ extra_rdoc_files:
|
|
49
49
|
- LICENSE
|
50
50
|
- README.rdoc
|
51
51
|
- lib/range_operators.rb
|
52
|
-
- lib/
|
52
|
+
- lib/range_operators/array_operator_definitions.rb
|
53
|
+
- lib/range_operators/range_operator_definitions.rb
|
53
54
|
files:
|
54
55
|
- LICENSE
|
55
|
-
- Manifest
|
56
56
|
- README.rdoc
|
57
57
|
- Rakefile
|
58
58
|
- lib/range_operators.rb
|
59
|
-
- lib/
|
59
|
+
- lib/range_operators/array_operator_definitions.rb
|
60
|
+
- lib/range_operators/range_operator_definitions.rb
|
61
|
+
- spec/array_operator_definitions_spec.rb
|
60
62
|
- spec/range_operators_spec.rb
|
63
|
+
- Manifest
|
61
64
|
- range_operators.gemspec
|
62
65
|
has_rdoc: true
|
63
66
|
homepage: http://github.com/monocle/range_operators
|
@@ -94,6 +97,6 @@ rubyforge_project: range_operators
|
|
94
97
|
rubygems_version: 1.3.6
|
95
98
|
signing_key:
|
96
99
|
specification_version: 3
|
97
|
-
summary: A gem that adds
|
100
|
+
summary: A gem that adds range methods to Ruby's Range and Array classes. (Range#+, Range#-, Array#rangify, Array#intersection, Array#missing)
|
98
101
|
test_files: []
|
99
102
|
|
metadata.gz.sig
CHANGED
Binary file
|
data/lib/rangify.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
#= Rangify
|
2
|
-
#
|
3
|
-
#This gem will add the rangify method to Ruby's Array class.
|
4
|
-
#The rangify method will produce appropriate ranges from the objects in the array.
|
5
|
-
#
|
6
|
-
#= Usage
|
7
|
-
#
|
8
|
-
#Examples:
|
9
|
-
#
|
10
|
-
#[1,2,3,6,7,8].rangify = [1..3, 6..8]
|
11
|
-
#
|
12
|
-
#[10..15, 16..20, 21, 22].rangify = [10..22]
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#Assumes inclusive ranges (ie. 1..4) and range.first <= range.last.
|
16
|
-
#
|
17
|
-
#Works with integers, dates and strings. However, all the objects in the array must be of the same class.
|
18
|
-
|
19
|
-
module Rangify
|
20
|
-
def rangify
|
21
|
-
array = self.uniq.sort_by { |element| comparison_value(element, :first) }
|
22
|
-
array.inject([]) do |collection, value|
|
23
|
-
unless collection.empty?
|
24
|
-
last = collection.last
|
25
|
-
last_value = comparison_value(last, :last)
|
26
|
-
current_value = comparison_value(value, :first)
|
27
|
-
if (last_value.succ <=> current_value) == -1
|
28
|
-
collection << value
|
29
|
-
else
|
30
|
-
first = [comparison_value(last, :first), comparison_value(value, :first)].min
|
31
|
-
second = [comparison_value(last, :last), comparison_value(value, :last)].max
|
32
|
-
collection[-1] = [first..second]
|
33
|
-
collection.flatten!
|
34
|
-
end
|
35
|
-
else
|
36
|
-
collection << value
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
# For a Range, will return value.first or value.last. A non-Range will return itself.
|
44
|
-
def comparison_value(value, position)
|
45
|
-
return value if value.class != Range
|
46
|
-
position == :first ? value.first : value.last
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class Array
|
51
|
-
include Rangify
|
52
|
-
end
|