flex_array 0.2.0 → 0.3.0
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.
- checksums.yaml +8 -8
- data/lib/flex_array.rb +19 -13
- data/lib/flex_array/array.rb +19 -19
- data/lib/flex_array/flex_array_append.rb +11 -11
- data/lib/flex_array/flex_array_each.rb +390 -53
- data/lib/flex_array/flex_array_forever.rb +18 -0
- data/lib/flex_array/flex_array_index.rb +13 -11
- data/lib/flex_array/flex_array_new.rb +30 -34
- data/lib/flex_array/flex_array_process.rb +42 -37
- data/lib/flex_array/flex_array_reshape.rb +13 -21
- data/lib/flex_array/flex_array_transpose.rb +15 -2
- data/lib/flex_array/flex_array_validate.rb +11 -11
- data/lib/flex_array/integer.rb +2 -4
- data/lib/flex_array/object.rb +2 -4
- data/lib/flex_array/range.rb +10 -14
- data/lib/flex_array/spec_array.rb +47 -0
- data/lib/flex_array/spec_component.rb +11 -11
- data/rakefile.rb +22 -2
- data/reek.txt +2 -29
- data/tests/array_test.rb +19 -24
- data/tests/flex_array_append_test.rb +10 -10
- data/tests/flex_array_each_test.rb +466 -93
- data/tests/flex_array_index_test.rb +55 -57
- data/tests/flex_array_new_test.rb +21 -21
- data/tests/flex_array_reshape_test.rb +10 -17
- data/tests/flex_array_test.rb +20 -12
- data/tests/flex_array_transpose_test.rb +33 -6
- data/tests/integer_test.rb +1 -1
- data/tests/object_test.rb +7 -7
- data/tests/range_test.rb +9 -8
- data/tests/spec_array_test.rb +26 -0
- data/tests/spec_component_test.rb +19 -16
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OWZiZTdkNTc4MmMyOTBiY2YwMjQ2ZTE5YmU1NWU0YWNmNzQ3MTRiNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjhmZmMxZjFlM2Q1YWM2MDc4YjRhMTVjM2FhOTRmYWE2NTE4MzU1NA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2FjMDgyYTRjZGY5NzQ2MzY5MzdjNTJhNGVjZDkyZjRiYTc3ZjBmZWMyMWVj
|
10
|
+
MGE1ZmU5NTBjMzQ0Y2ViOGEyYTc5ZGFmMGQyZGE4YzljYzMzNGU4NWQ4MTRm
|
11
|
+
NjQzOWEzNGMwZGM3OTE0YjFkZWE1ODljMTY1YzE2MzEwZTkyOWU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZTNmMDUwOGEyNGRmYzljZjhjMjhlOWQ1NjVjMjlmNDA4MjZhODAyM2I2OWIy
|
14
|
+
NmU4ZWU4M2Y2OWEyOTlkZjgxZmIxZTczM2YxZWNkZDI2YzY4ZTVjMzNlMGMy
|
15
|
+
ODU1NGU2NWY5YTZhOTQzNjAyNWJjZGJjNGRiMjU3ZjQ2YmI4MzM=
|
data/lib/flex_array.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'in_array'
|
2
|
+
require_relative 'flex_array/flex_array_forever'
|
2
3
|
require_relative 'flex_array/spec_component'
|
4
|
+
require_relative 'flex_array/spec_array'
|
3
5
|
require_relative 'flex_array/object'
|
4
6
|
require_relative 'flex_array/integer'
|
5
7
|
require_relative 'flex_array/range'
|
@@ -17,14 +19,13 @@ require_relative 'flex_array/flex_array_process'
|
|
17
19
|
#\FlexArray - A flexible array class.
|
18
20
|
#* flex_array.rb - The root file that gathers up all the flex array parts.
|
19
21
|
class FlexArray
|
20
|
-
include Enumerable
|
21
22
|
include InArrayAlready
|
22
23
|
|
23
24
|
#The version of this class.
|
24
25
|
#<br>Returns
|
25
26
|
#* A version string; <major>.<minor>.<step>
|
26
27
|
def self.version
|
27
|
-
'0.
|
28
|
+
'0.3.0'
|
28
29
|
end
|
29
30
|
|
30
31
|
#The version of the class of this instance.
|
@@ -41,16 +42,23 @@ class FlexArray
|
|
41
42
|
attr_accessor :array_data
|
42
43
|
|
43
44
|
#The total number of elements in this array.
|
44
|
-
|
45
|
+
def length
|
46
|
+
@array_specs.spec_count
|
47
|
+
end
|
48
|
+
|
49
|
+
alias size length
|
45
50
|
|
46
51
|
#The number of dimensions in this array.
|
47
|
-
|
52
|
+
def dimensions
|
53
|
+
@array_specs.spec_dimensions
|
54
|
+
end
|
55
|
+
|
56
|
+
#Is this flex array transposed?
|
57
|
+
attr_reader :transposed
|
48
58
|
|
49
59
|
#Get the limits of the subscripts of the flex array.
|
50
|
-
#<br>Returns
|
51
|
-
#* An array of dimension limits ranges.
|
52
60
|
def limits
|
53
|
-
|
61
|
+
@array_specs.collect {|spec| spec.range }
|
54
62
|
end
|
55
63
|
|
56
64
|
#Return this flex array as a flex array!
|
@@ -79,11 +87,9 @@ class FlexArray
|
|
79
87
|
def <=>(other)
|
80
88
|
@array_data <=> other.array_data
|
81
89
|
end
|
82
|
-
|
83
|
-
#
|
84
|
-
def
|
85
|
-
|
86
|
-
@count = @array_data.length
|
87
|
-
self
|
90
|
+
|
91
|
+
#Is this flex array empty?
|
92
|
+
def empty?
|
93
|
+
length == 0
|
88
94
|
end
|
89
95
|
end
|
data/lib/flex_array/array.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative '../flex_array'
|
2
|
-
|
3
1
|
#Extensions to Array needed to support flex array.
|
4
2
|
class Array
|
5
3
|
#Get the specifications of the array index values.
|
@@ -8,23 +6,21 @@ class Array
|
|
8
6
|
def limits
|
9
7
|
[0...self.length]
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
#Quick access to the limits for internal use.
|
13
11
|
#<br>Returns
|
14
12
|
#* An array with one spec component in it.
|
15
13
|
def array_specs
|
16
|
-
|
14
|
+
SpecArray.new([0...self.length])
|
17
15
|
end
|
18
|
-
|
16
|
+
|
19
17
|
#Quick access to the array data for internal use.
|
20
18
|
#<br>Returns
|
21
19
|
#* An array -- self
|
22
20
|
def array_data
|
23
21
|
self
|
24
22
|
end
|
25
|
-
|
26
|
-
alias :length :count
|
27
|
-
|
23
|
+
|
28
24
|
#Convert this array to an range index against the spec.
|
29
25
|
#<br>Parameters
|
30
26
|
#* spec - The spec component used to validate this index.
|
@@ -33,22 +29,26 @@ class Array
|
|
33
29
|
#<br>Exceptions
|
34
30
|
#* IndexError if the range is not valid.
|
35
31
|
def to_index_range(spec)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
spec_max = spec.max
|
33
|
+
|
34
|
+
self.collect do |value|
|
35
|
+
value = Integer(value)
|
36
|
+
value = spec_max + value + 1 if value < 0
|
37
|
+
|
38
|
+
unless spec === value
|
39
|
+
fail IndexError, "Subscript invalid or out of range: #{self.inspect}"
|
40
|
+
end
|
41
|
+
|
42
|
+
value
|
44
43
|
end
|
45
|
-
end
|
46
|
-
|
44
|
+
end
|
45
|
+
|
47
46
|
#Return this flex array as a flex array!
|
48
47
|
#<br>Returns
|
49
48
|
#* A flex array that references this array.
|
50
49
|
#<br>Note
|
51
|
-
#* To avoid a shared reference, use my_array.dup.to_flex_array
|
50
|
+
#* To avoid a shared reference, use my_array.dup.to_flex_array or
|
51
|
+
# FlexArray.new_from_array(my_array.dup) instead.
|
52
52
|
def to_flex_array
|
53
53
|
FlexArray.new_from_array(self)
|
54
54
|
end
|
@@ -8,10 +8,10 @@ class FlexArray
|
|
8
8
|
#<br>Exceptions
|
9
9
|
#* ArgumentError if the data may not be appended.
|
10
10
|
def << (data)
|
11
|
+
fail "Cannot append to a transposed array." if @transposed
|
11
12
|
specs = get_append_specs(data = data.in_array)
|
12
|
-
|
13
|
-
@array_specs
|
14
|
-
@count += data.count
|
13
|
+
@array_data += data.array_data
|
14
|
+
@array_specs.enlarge(specs[0].span)
|
15
15
|
self
|
16
16
|
end
|
17
17
|
|
@@ -33,19 +33,19 @@ class FlexArray
|
|
33
33
|
#* ArgumentError if the data may not be appended.
|
34
34
|
def get_append_specs(data)
|
35
35
|
spec_len = (specs = data.array_specs).length
|
36
|
-
|
37
|
-
if
|
38
|
-
specs.insert(0, SpecComponent.new(0...1, nil))
|
39
|
-
elsif
|
36
|
+
|
37
|
+
if dimensions == spec_len+1
|
38
|
+
specs = specs.dup.insert(0, SpecComponent.new(0...1, nil))
|
39
|
+
elsif dimensions != spec_len
|
40
40
|
fail ArgumentError, "Incompatible dimensionality error on <<."
|
41
41
|
end
|
42
|
-
|
43
|
-
(1
|
44
|
-
unless @array_specs[index] == specs[index]
|
42
|
+
|
43
|
+
(1...dimensions).each do |index|
|
44
|
+
unless @array_specs[index].span == specs[index].span
|
45
45
|
fail ArgumentError, "Dimension mismatch error on <<."
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
specs
|
50
50
|
end
|
51
51
|
end
|
@@ -1,98 +1,435 @@
|
|
1
1
|
#* flex_array_each.rb - The flexible array class each and related methods.
|
2
|
+
# :reek:RepeatedConditional - @transposed determines if short cuts are allowed.
|
2
3
|
class FlexArray
|
3
|
-
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
#Retrieve data from the array endlessly repeating as needed.
|
4
7
|
#<br>Parameters
|
5
|
-
#*
|
6
|
-
#
|
7
|
-
# a splat parameter, it must be passed as an array explicitly. If omitted
|
8
|
-
# or passed in as [:all] all elements of the array are processed.
|
8
|
+
#* count - The number of times to cycle through the flex array. Defaults to
|
9
|
+
# cycling forever.
|
9
10
|
#* block - The optional block to be executed for each selected array element.
|
10
|
-
# The return value is the last value returned by the block. If the block
|
11
|
-
# is not present, an enumerator object is returned.
|
11
|
+
# The return value is the last value returned by the block. If the block
|
12
|
+
# is not present, then an enumerator object is returned.
|
13
|
+
#<br>Returns
|
14
|
+
#* nil or an enumerator if no block is provided.
|
12
15
|
#<br>Block Arguments
|
13
16
|
#* value - Each value selected by the iteration.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
#<br>Endemic Code Smells
|
18
|
+
#* :reek:NestedIterators
|
19
|
+
def cycle(count = FOREVER, &block)
|
20
|
+
if block_given?
|
21
|
+
if @transposed && length > 0
|
22
|
+
count.times do
|
23
|
+
process_all do |_index, posn|
|
24
|
+
block.call(@array_data[posn])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
nil
|
29
|
+
else
|
30
|
+
@array_data.cycle(count.to_i, &block)
|
22
31
|
end
|
32
|
+
else
|
33
|
+
self.to_enum(:cycle, count)
|
23
34
|
end
|
24
35
|
end
|
25
36
|
|
26
|
-
#Retrieve data from the array endlessly repeating as needed.
|
37
|
+
#Retrieve data from a subset of the flex array endlessly repeating as needed.
|
27
38
|
#<br>Parameters
|
28
|
-
#* indexes - An array with as many entries as the flexible array has
|
39
|
+
#* indexes - An array with as many entries as the flexible array has
|
29
40
|
# dimensions. See [] for more details. Note that since indexes is NOT
|
30
|
-
# a splat parameter, it must be passed as an array explicitly.
|
31
|
-
|
41
|
+
# a splat parameter, it must be passed as an array explicitly.
|
42
|
+
#* count - The number of times to cycle through the flex array. Defaults to
|
43
|
+
# cycling forever.
|
32
44
|
#* block - The optional block to be executed for each selected array element.
|
33
|
-
# The return value is the last value returned by the block. If the block
|
45
|
+
# The return value is the last value returned by the block. If the block
|
34
46
|
# is not present, then an enumerator object is returned.
|
47
|
+
#<br>Returns
|
48
|
+
#* nil or an enumerator if no block is provided.
|
35
49
|
#<br>Block Arguments
|
36
|
-
#* value - Each value selected by the iteration.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
50
|
+
#* value - Each value selected by the iteration.
|
51
|
+
#<br>Endemic Code Smells
|
52
|
+
#* :reek:NestedIterators
|
53
|
+
def select_cycle(indexes, count = FOREVER, &block)
|
54
|
+
validate_index_count(indexes)
|
55
|
+
|
56
|
+
if block_given?
|
57
|
+
unless empty?
|
58
|
+
count.times do
|
59
|
+
process_indexes(indexes) do |_index, posn|
|
60
|
+
block.call(@array_data[posn])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
nil
|
42
66
|
else
|
43
|
-
|
44
|
-
|
67
|
+
self.to_enum(:select_cycle, indexes, count)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#Process the standard each operator.
|
72
|
+
#<br>Parameters
|
73
|
+
#* block - The optional block to be executed for each selected array element.
|
74
|
+
#<br>Returns
|
75
|
+
#* If the block is not present, then an enumerator object is returned.
|
76
|
+
# Otherwise the flex array is returned.
|
77
|
+
#<br>Block Arguments
|
78
|
+
#* value - Each value selected by the iteration.
|
79
|
+
def each(&block)
|
80
|
+
if block_given?
|
81
|
+
if @transposed
|
82
|
+
process_all {|_index, posn| block.call(@array_data[posn])}
|
83
|
+
else
|
84
|
+
@array_data.each(&block)
|
45
85
|
end
|
86
|
+
|
87
|
+
self
|
88
|
+
else
|
89
|
+
self.to_enum(:each)
|
46
90
|
end
|
47
91
|
end
|
48
|
-
|
49
|
-
#Process the
|
92
|
+
|
93
|
+
#Process the enhanced select_each operator.
|
50
94
|
#<br>Parameters
|
51
|
-
#* indexes - An array with as many entries as the flexible array has
|
95
|
+
#* indexes - An array with as many entries as the flexible array has
|
52
96
|
# dimensions. See [] for more details. Note that since indexes is NOT
|
53
|
-
# a splat parameter, it must be passed as an array explicitly
|
54
|
-
# or passed in as [:all] all elements of the array are processed.
|
97
|
+
# a splat parameter, it must be passed as an array explicitly
|
55
98
|
#* block - The optional block to be executed for each selected array element.
|
56
|
-
|
57
|
-
|
99
|
+
#<br>Returns
|
100
|
+
#* If the block is not present, then an enumerator object is returned.
|
101
|
+
# Otherwise the flex array is returned.
|
102
|
+
#<br>Block Arguments
|
103
|
+
#* value - Each value selected by the iteration.
|
104
|
+
def select_each(indexes, &block)
|
105
|
+
validate_index_count(indexes)
|
106
|
+
|
107
|
+
if block_given?
|
108
|
+
process_indexes(indexes) {|_index, posn| block.call(@array_data[posn])}
|
109
|
+
self
|
110
|
+
else
|
111
|
+
self.to_enum(:select_each, indexes)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
#Process the standard each_with_index operator.
|
116
|
+
#<br>Parameters
|
117
|
+
#* block - The optional block to be executed for each selected array element.
|
118
|
+
#<br>Returns
|
119
|
+
#* If the block is not present, then an enumerator object is returned.
|
120
|
+
# Otherwise the flex array is returned.
|
58
121
|
#<br>Block Arguments
|
59
122
|
#* value - Each value selected by the iteration.
|
60
123
|
#* index - An array with the full index of the selected value.
|
61
|
-
def each_with_index(
|
62
|
-
|
124
|
+
def each_with_index(&block)
|
125
|
+
if block_given?
|
126
|
+
process_all {|index, posn| block.call(@array_data[posn], index)}
|
127
|
+
self
|
128
|
+
else
|
129
|
+
self.to_enum(:each_with_index)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
#Process the enhanced select_each_with_index operator.
|
134
|
+
#<br>Parameters
|
135
|
+
#* indexes - An array with as many entries as the flexible array has
|
136
|
+
# dimensions. See [] for more details. Note that since indexes is NOT
|
137
|
+
# a splat parameter, it must be passed as an array explicitly.
|
138
|
+
#* block - The optional block to be executed for each selected array element.
|
139
|
+
#<br>Returns
|
140
|
+
#* If the block is not present, then an enumerator object is returned.
|
141
|
+
# Otherwise the flex array is returned.
|
142
|
+
#<br>Block Arguments
|
143
|
+
#* value - Each value selected by the iteration.
|
144
|
+
#* index - An array with the full index of the selected value.
|
145
|
+
def select_each_with_index(indexes, &block)
|
146
|
+
validate_index_count(indexes)
|
63
147
|
|
64
148
|
if block_given?
|
65
149
|
process_indexes(indexes) {|index, posn| block.call(@array_data[posn], index)}
|
150
|
+
self
|
66
151
|
else
|
67
|
-
|
68
|
-
process_indexes(indexes) {|index, posn| yielder.yield(@array_data[posn], index)}
|
69
|
-
end
|
152
|
+
self.to_enum(:select_each_with_index, indexes)
|
70
153
|
end
|
71
154
|
end
|
72
|
-
|
73
|
-
#A specialized each variant that passes the low level data, the index
|
155
|
+
|
156
|
+
#A specialized each variant that passes the low level data, the index
|
74
157
|
#and the position to the block.
|
75
158
|
#<br>Parameters
|
76
|
-
#*
|
159
|
+
#* block - The optional block to be executed for each selected array element.
|
160
|
+
# The return value is the last value returned by the block. If the block
|
161
|
+
# is not present, then an enumerator object is returned.
|
162
|
+
#<br>Returns
|
163
|
+
#* If the block is not present, then an enumerator object is returned.
|
164
|
+
# Otherwise the flex array is returned.
|
165
|
+
#<br>Block Arguments
|
166
|
+
#* index - An array with the full index of the selected value.
|
167
|
+
#* posn - The position of the data in the low level data store.
|
168
|
+
def _each_raw(&block)
|
169
|
+
if block_given?
|
170
|
+
process_all {|index, posn| block.call(index, posn)}
|
171
|
+
self
|
172
|
+
else
|
173
|
+
self.to_enum(:_each_raw)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
#An enhanced specialized each variant that passes the low level data,
|
178
|
+
#the index and the position to the block.
|
179
|
+
#<br>Parameters
|
180
|
+
#* indexes - An array with as many entries as the flexible array has
|
77
181
|
# dimensions. See [] for more details. Note that since indexes is NOT
|
78
|
-
# a splat parameter, it must be passed as an array explicitly.
|
79
|
-
# or passed in as [:all] all elements of the array are processed.
|
182
|
+
# a splat parameter, it must be passed as an array explicitly.
|
80
183
|
#* block - The optional block to be executed for each selected array element.
|
81
|
-
# The return value is the last value returned by the block. If the block
|
184
|
+
# The return value is the last value returned by the block. If the block
|
82
185
|
# is not present, then an enumerator object is returned.
|
186
|
+
#<br>Returns
|
187
|
+
#* If the block is not present, then an enumerator object is returned.
|
188
|
+
# Otherwise the flex array is returned.
|
83
189
|
#<br>Block Arguments
|
84
|
-
#* data - A reference to the low level data store.
|
85
190
|
#* index - An array with the full index of the selected value.
|
86
191
|
#* posn - The position of the data in the low level data store.
|
87
|
-
def
|
88
|
-
|
192
|
+
def _select_each_raw(indexes, &block)
|
193
|
+
validate_index_count(indexes)
|
194
|
+
|
195
|
+
if block_given?
|
196
|
+
process_indexes(indexes) {|index, posn| block.call(index, posn)}
|
197
|
+
self
|
198
|
+
else
|
199
|
+
self.to_enum(:_select_each_raw, indexes)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
alias_method :flatten_collect, :collect
|
204
|
+
|
205
|
+
#The flex array version of collect that returns a flex array.
|
206
|
+
#<br>Parameters
|
207
|
+
#* block - The optional block to be executed for each selected array element.
|
208
|
+
#<br>Returns
|
209
|
+
#* An array of the computed objects retuned by the block.
|
210
|
+
#<br>Block Arguments
|
211
|
+
#* value - Each value selected by the iteration.
|
212
|
+
def collect(&block)
|
213
|
+
result = self.dup
|
214
|
+
result.collect!(&block)
|
215
|
+
end
|
216
|
+
|
217
|
+
#The flex array version of collect that accepts an optional set of indexes
|
218
|
+
#to select the data being collected into a flex array.
|
219
|
+
#<br>Parameters
|
220
|
+
#* indexes - An array with as many entries as the flexible array has
|
221
|
+
# dimensions. See [] for more details. Note that since indexes is NOT
|
222
|
+
# a splat parameter, it must be passed as an array explicitly.
|
223
|
+
#* block - The optional block to be executed for each selected array element.
|
224
|
+
#<br>Returns
|
225
|
+
#* An array of the computed objects retuned by the block.
|
226
|
+
# If the block is not present, an enumerator object is returned.
|
227
|
+
#<br>Block Arguments
|
228
|
+
#* value - Each value selected by the iteration.
|
229
|
+
def select_collect(indexes, &block)
|
230
|
+
result = self.dup
|
231
|
+
result.select_collect!(indexes, &block)
|
232
|
+
end
|
233
|
+
|
234
|
+
#The flex array version of collect that accepts an optional set of indexes
|
235
|
+
#to select the data being collected into a standard array.
|
236
|
+
#<br>Parameters
|
237
|
+
#* indexes - An array with as many entries as the flexible array has
|
238
|
+
# dimensions. See [] for more details. Note that since indexes is NOT
|
239
|
+
# a splat parameter, it must be passed as an array explicitly.
|
240
|
+
#* block - The optional block to be executed for each selected array element.
|
241
|
+
#<br>Returns
|
242
|
+
#* An array of the computed objects retuned by the block.
|
243
|
+
# If the block is not present, an enumerator object is returned.
|
244
|
+
#<br>Block Arguments
|
245
|
+
#* value - Each value selected by the iteration.
|
246
|
+
def select_flatten_collect(indexes, &block)
|
247
|
+
validate_index_count(indexes)
|
89
248
|
|
90
249
|
if block_given?
|
91
|
-
|
250
|
+
result = []
|
251
|
+
process_indexes(indexes) {|_index, posn| result << block.call(@array_data[posn])}
|
252
|
+
result
|
253
|
+
else
|
254
|
+
self.to_enum(:select_collect, indexes)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
#The flex array version of collect!
|
259
|
+
#<br>Parameters
|
260
|
+
#* block - The *required* block to be executed for each selected array element.
|
261
|
+
# The return value is the last value returned by the block. If the block
|
262
|
+
# is not present, an enumerator object is returned.
|
263
|
+
#<br>Returns
|
264
|
+
#* self
|
265
|
+
#<br>Block Arguments
|
266
|
+
#* value - Each value selected by the iteration.
|
267
|
+
def collect!(&block)
|
268
|
+
fail ArgumentError, "A block is required." unless block_given?
|
269
|
+
|
270
|
+
if @transposed
|
271
|
+
process_all {|_index, posn| @array_data[posn] =
|
272
|
+
block.call(@array_data[posn])}
|
92
273
|
else
|
93
|
-
|
94
|
-
|
274
|
+
@array_data = @array_data.collect(&block)
|
275
|
+
end
|
276
|
+
|
277
|
+
self
|
278
|
+
end
|
279
|
+
|
280
|
+
#The enhanced flex array version of collect! that accepts a set of indexes
|
281
|
+
#to select the data being collected.
|
282
|
+
#<br>Parameters
|
283
|
+
#* indexes - An array with as many entries as the flexible array has
|
284
|
+
# dimensions. See [] for more details. Note that since indexes is NOT
|
285
|
+
# a splat parameter, it must be passed as an array explicitly.
|
286
|
+
#* block - The *required* block to be executed for each selected array element.
|
287
|
+
# The return value is the last value returned by the block. If the block
|
288
|
+
# is not present, an enumerator object is returned.
|
289
|
+
#<br>Returns
|
290
|
+
#* self
|
291
|
+
#<br>Block Arguments
|
292
|
+
#* value - Each value selected by the iteration.
|
293
|
+
def select_collect!(indexes, &block)
|
294
|
+
fail ArgumentError, "A block is required." unless block_given?
|
295
|
+
validate_index_count(indexes)
|
296
|
+
|
297
|
+
process_indexes(indexes) {|_index, posn| @array_data[posn] =
|
298
|
+
block.call(@array_data[posn])}
|
299
|
+
|
300
|
+
self
|
301
|
+
end
|
302
|
+
|
303
|
+
#The flex array version of find_index. This returns the
|
304
|
+
#coordinates of the first object that matches the search object or is
|
305
|
+
#flagged true by the search block.
|
306
|
+
#<br>Parameters
|
307
|
+
#* object - The optional value to search for.
|
308
|
+
#* block - The optional block to be executed for each selected array element.
|
309
|
+
# If the block or object are not present, an enumerator object is returned.
|
310
|
+
#<br>Returns
|
311
|
+
#* The index of the first place that matched or nil if none matched.
|
312
|
+
#<br>Block Arguments
|
313
|
+
#* value - Each value selected by the iteration.
|
314
|
+
def find_index(value = nil, &block)
|
315
|
+
blk = get_find_block(value, &block)
|
316
|
+
|
317
|
+
if blk
|
318
|
+
process_all do |index, posn|
|
319
|
+
if blk.call(@array_data[posn])
|
320
|
+
return index
|
321
|
+
end
|
95
322
|
end
|
323
|
+
|
324
|
+
nil
|
325
|
+
else
|
326
|
+
self.to_enum(:find_index)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
#The enhanced flex array version of find_index. This returns the
|
331
|
+
#coordinates of the first object that matches the search object or is
|
332
|
+
#flagged true by the search block.
|
333
|
+
#<br>Parameters
|
334
|
+
#* indexes - An array with as many entries as the flexible array has
|
335
|
+
# dimensions. See [] for more details. Note that since indexes is NOT
|
336
|
+
# a splat parameter, it must be passed as an array explicitly.
|
337
|
+
#* object - The optional value to search for.
|
338
|
+
#* block - The optional block to be executed for each selected array element.
|
339
|
+
# If the block or object are not present, an enumerator object is returned.
|
340
|
+
#<br>Returns
|
341
|
+
#* The index of the first place that matched or nil if none matched.
|
342
|
+
#<br>Block Arguments
|
343
|
+
#* value - Each value selected by the iteration.
|
344
|
+
def select_find_index(indexes, value = nil, &block)
|
345
|
+
validate_index_count(indexes)
|
346
|
+
blk = get_find_block(value, &block)
|
347
|
+
|
348
|
+
if blk
|
349
|
+
process_indexes(indexes) do |index, posn|
|
350
|
+
if blk.call(@array_data[posn])
|
351
|
+
return index
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
nil
|
356
|
+
else
|
357
|
+
self.to_enum(:select_find_index, indexes)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
#The improved flex array version of find_index. This returns the
|
362
|
+
#coordinates of objects that match the search object or are
|
363
|
+
#flagged true by the search block.
|
364
|
+
#<br>Parameters
|
365
|
+
#* object - The optional value to search for.
|
366
|
+
#* block - The optional block to be executed for each selected array element.
|
367
|
+
# If the block or object are not present, an enumerator object is returned.
|
368
|
+
#<br>Returns
|
369
|
+
#* An array of the indexes of the places that matched.
|
370
|
+
#<br>Block Arguments
|
371
|
+
#* value - Each value selected by the iteration.
|
372
|
+
def find_indexes(value = nil, &block)
|
373
|
+
blk, result = get_find_block(value, &block), []
|
374
|
+
|
375
|
+
if blk
|
376
|
+
process_all do |index, posn|
|
377
|
+
if blk.call(@array_data[posn])
|
378
|
+
result << index.dup
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
result
|
383
|
+
else
|
384
|
+
self.to_enum(:find_indexes)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
#The enhanced and improved flex array version of find_index. This returns the
|
389
|
+
#coordinates of objects that match the search object or are
|
390
|
+
#flagged true by the search block.
|
391
|
+
#<br>Parameters
|
392
|
+
#* indexes - An array with as many entries as the flexible array has
|
393
|
+
# dimensions. See [] for more details. Note that since indexes is NOT
|
394
|
+
# a splat parameter, it must be passed as an array explicitly.
|
395
|
+
#* object - The optional value to search for.
|
396
|
+
#* block - The optional block to be executed for each selected array element.
|
397
|
+
# If the block or object are not present, an enumerator object is returned.
|
398
|
+
#<br>Returns
|
399
|
+
#* An array of the indexes of the places that matched.
|
400
|
+
#<br>Block Arguments
|
401
|
+
#* value - Each value selected by the iteration.
|
402
|
+
def select_find_indexes(indexes, value = nil, &block)
|
403
|
+
validate_index_count(indexes)
|
404
|
+
blk, result = get_find_block(value, &block), []
|
405
|
+
|
406
|
+
if blk
|
407
|
+
process_indexes(indexes) do |index, posn|
|
408
|
+
if blk.call(@array_data[posn])
|
409
|
+
result << index.dup
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
result
|
414
|
+
else
|
415
|
+
self.to_enum(:select_find_index, indexes)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
private
|
420
|
+
|
421
|
+
#A helper method to determine which block to use in the find_index family.
|
422
|
+
#<br>Returns
|
423
|
+
#* The block to use or nil.
|
424
|
+
#<br>Endemic Code Smells
|
425
|
+
#* :reek:NilCheck
|
426
|
+
def get_find_block(value, &block)
|
427
|
+
if block_given?
|
428
|
+
block
|
429
|
+
elsif value.nil?
|
430
|
+
nil
|
431
|
+
else
|
432
|
+
lambda {|obj| obj == value }
|
96
433
|
end
|
97
434
|
end
|
98
|
-
end
|
435
|
+
end
|