range_operators 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|