Class: FlexArray
- Includes:
- Enumerable, InArrayAlready
- Defined in:
- lib/flex_array.rb,
lib/flex_array/version.rb,
lib/flex_array/flex_array_new.rb,
lib/flex_array/flex_array_each.rb,
lib/flex_array/flex_array_index.rb,
lib/flex_array/flex_array_append.rb,
lib/flex_array/flex_array_forever.rb,
lib/flex_array/flex_array_process.rb,
lib/flex_array/flex_array_reshape.rb,
lib/flex_array/flex_array_validate.rb,
lib/flex_array/flex_array_transpose.rb
Overview
The flexible array class transpose and related methods.
Defined Under Namespace
Classes: ForEver
Constant Summary collapse
- VERSION =
The version string for flex array.
"0.3.7".freeze
- FOREVER =
Create a forever constant for use where infinite looping is needed.
ForEver.new
Instance Attribute Summary collapse
-
#array_data ⇒ Object
The underlying array data used by the flex array.
-
#array_specs ⇒ Object
The array specifications.
-
#transposed ⇒ Object
readonly
Is this flex array transposed?.
Class Method Summary collapse
-
.new_from(array_specs, other) ⇒ Object
Construct a flex array using other as a template or data source.
-
.new_from_array(other) ⇒ Object
Construct a flex array as a duplicate of a source array or flex array.
-
.new_from_selection(array_specs, other, selection) ⇒ Object
Construct a flex array using a all or a portion of portion of another flex array as a data source.
-
.version ⇒ Object
The version of this class.
Instance Method Summary collapse
-
#<<(data) ⇒ Object
Append to the flex array.
-
#<=>(other) ⇒ Object
Make FlexArrays comparable with the compariositality method.
-
#==(other) ⇒ Object
Are these FlexArrays equal?.
-
#[](*indexes) ⇒ Object
Retrieve the selected data from the flex array.
-
#[]=(*indexes, value) ⇒ Object
Store the value data into the flex array.
-
#_each_raw(&block) ⇒ Object
A specialized each variant that passes the low level data, the index and the position to the block.
-
#_select_each_raw(indexes, &block) ⇒ Object
An enhanced specialized each variant that passes the low level data, the index and the position to the block.
-
#collect(&block) ⇒ Object
The flex array version of collect that returns a flex array.
-
#collect!(&block) ⇒ Object
The flex array version of collect!.
-
#compatible?(other) ⇒ Boolean
Is this array compatible with other?.
-
#cycle(count = FOREVER, &block) ⇒ Object
Retrieve data from the array endlessly repeating as needed.
-
#dimensions ⇒ Object
The number of dimensions in this array.
-
#dup ⇒ Object
Create a duplicate of this array.
-
#each(&block) ⇒ Object
Process the standard each operator.
-
#each_with_index(&block) ⇒ Object
Process the standard each_with_index operator.
-
#empty? ⇒ Boolean
Is this flex array empty?.
-
#find_index(value = nil, &block) ⇒ Object
The flex array version of find_index.
-
#find_indexes(value = nil, &block) ⇒ Object
The improved flex array version of find_index.
- #flatten_collect ⇒ Object
-
#initialize(array_specs, default = nil, &init_block) ⇒ FlexArray
constructor
Construct a flexible array object.
-
#length ⇒ Object
(also: #size)
The total number of elements in this array.
-
#limits ⇒ Object
Get the limits of the subscripts of the flex array.
-
#reshape(array_specs) ⇒ Object
Return a copy of this flex array, recast in a new shape, dropping or repeating data elements as required.
-
#reshape!(array_specs) ⇒ Object
Recast this flex array in a new shape, dropping or repeating data elements as required.
-
#select_collect(indexes, &block) ⇒ Object
The flex array version of collect that accepts an optional set of indexes to select the data being collected into a flex array.
-
#select_collect!(indexes, &block) ⇒ Object
The enhanced flex array version of collect! that accepts a set of indexes to select the data being collected.
-
#select_cycle(indexes, count = FOREVER, &block) ⇒ Object
Retrieve data from a subset of the flex array endlessly repeating as needed.
-
#select_each(indexes, &block) ⇒ Object
Process the enhanced select_each operator.
-
#select_each_with_index(indexes, &block) ⇒ Object
Process the enhanced select_each_with_index operator.
-
#select_find_index(indexes, value = nil, &block) ⇒ Object
The enhanced flex array version of find_index.
-
#select_find_indexes(indexes, value = nil, &block) ⇒ Object
The enhanced and improved flex array version of find_index.
-
#select_flatten_collect(indexes, &block) ⇒ Object
The flex array version of collect that accepts an optional set of indexes to select the data being collected into a standard array.
- #shallow_dup ⇒ Object
-
#to_a ⇒ Object
Convert the flex array to a simple array.
-
#to_flex_array ⇒ Object
Return this flex array as a flex array!.
-
#transpose(dim_a, dim_b) ⇒ Object
Return a reference to this array’s data with the specified dimensions transposed.
-
#transpose!(dim_a, dim_b) ⇒ Object
Transpose the specified dimensions.
-
#version ⇒ Object
The version of the class of this instance.
Constructor Details
#initialize(array_specs, default = nil, &init_block) ⇒ FlexArray
Construct a flexible array object.
4 5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/flex_array/flex_array_new.rb', line 4 def initialize(array_specs, default=nil, &init_block) @array_specs = SpecArray.new(array_specs.in_array) @transposed = false # Allocate the data for the array. @array_data = Array.new(@array_specs.spec_count, default) # Set up the array with the optional init_block. if init_block process_all {|index, posn| @array_data[posn] = init_block.call(index)} end end |
Instance Attribute Details
#array_data ⇒ Object
The underlying array data used by the flex array.
40 41 42 |
# File 'lib/flex_array.rb', line 40 def array_data @array_data end |
#array_specs ⇒ Object
The array specifications. An array of spec components.
37 38 39 |
# File 'lib/flex_array.rb', line 37 def array_specs @array_specs end |
#transposed ⇒ Object (readonly)
Is this flex array transposed?
55 56 57 |
# File 'lib/flex_array.rb', line 55 def transposed @transposed end |
Class Method Details
.new_from(array_specs, other) ⇒ Object
Construct a flex array using other as a template or data source.
28 29 30 31 |
# File 'lib/flex_array/flex_array_new.rb', line 28 def self.new_from(array_specs, other) iterator = other.array_data.cycle FlexArray.new(array_specs) {iterator.next} end |
.new_from_array(other) ⇒ Object
Construct a flex array as a duplicate of a source array or flex array.
41 42 43 44 45 46 |
# File 'lib/flex_array/flex_array_new.rb', line 41 def self.new_from_array(other) result = FlexArray.new(0) result.array_specs = other.array_specs.dup result.array_data = other.array_data result end |
.new_from_selection(array_specs, other, selection) ⇒ Object
Construct a flex array using a all or a portion of portion of another flex array as a data source.
35 36 37 38 |
# File 'lib/flex_array/flex_array_new.rb', line 35 def self.new_from_selection(array_specs, other, selection) iterator = other.select_cycle(selection) FlexArray.new(array_specs) {iterator.next} end |
Instance Method Details
#<<(data) ⇒ Object
Append to the flex array.
5 6 7 8 9 10 11 |
# File 'lib/flex_array/flex_array_append.rb', line 5 def << (data) fail "Cannot append to a transposed array." if @transposed specs = get_append_specs(data = data.in_array) @array_data += data.array_data @array_specs.enlarge(specs[0].span) self end |
#<=>(other) ⇒ Object
Make FlexArrays comparable with the compariositality method.
73 74 75 |
# File 'lib/flex_array.rb', line 73 def <=>(other) @array_data <=> other.array_data end |
#==(other) ⇒ Object
Are these FlexArrays equal?
68 69 70 |
# File 'lib/flex_array.rb', line 68 def ==(other) self.compatible?(other) && @array_data == other.array_data end |
#[](*indexes) ⇒ Object
Retrieve the selected data from the flex array.
5 6 7 8 9 10 |
# File 'lib/flex_array/flex_array_index.rb', line 5 def [](*indexes) validate_index_count(indexes) result = [] process_indexes(indexes) {|_index, posn| result << @array_data[posn]} result.length == 1 ? result[0] : result end |
#[]=(*indexes, value) ⇒ Object
Store the value data into the flex array.
13 14 15 16 17 18 |
# File 'lib/flex_array/flex_array_index.rb', line 13 def []=(*indexes, value) validate_index_count(indexes) source = value.in_array.cycle process_indexes(indexes) {|_index, posn| @array_data[posn] = source.next} value end |
#_each_raw(&block) ⇒ Object
A specialized each variant that passes the low level data, the index and the position to the block.
95 96 97 98 99 100 101 102 |
# File 'lib/flex_array/flex_array_each.rb', line 95 def _each_raw(&block) if block_given? process_all {|index, posn| block.call(index, posn)} self else self.to_enum(:_each_raw) end end |
#_select_each_raw(indexes, &block) ⇒ Object
An enhanced specialized each variant that passes the low level data, the index and the position to the block.
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/flex_array/flex_array_each.rb', line 106 def _select_each_raw(indexes, &block) validate_index_count(indexes) if block_given? process_indexes(indexes) {|index, posn| block.call(index, posn)} self else self.to_enum(:_select_each_raw, indexes) end end |
#collect(&block) ⇒ Object
The flex array version of collect that returns a flex array.
120 121 122 123 |
# File 'lib/flex_array/flex_array_each.rb', line 120 def collect(&block) result = self.dup result.collect!(&block) end |
#collect!(&block) ⇒ Object
The flex array version of collect!
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/flex_array/flex_array_each.rb', line 147 def collect!(&block) fail ArgumentError, "A block is required." unless block_given? if @transposed process_all {|_index, posn| @array_data[posn] = block.call(@array_data[posn])} else @array_data = @array_data.collect(&block) end self end |
#compatible?(other) ⇒ Boolean
Is this array compatible with other?
5 6 7 8 9 |
# File 'lib/flex_array/flex_array_validate.rb', line 5 def compatible?(other) @array_specs == other.array_specs rescue false end |
#cycle(count = FOREVER, &block) ⇒ Object
Retrieve data from the array endlessly repeating as needed.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/flex_array/flex_array_each.rb', line 7 def cycle(count = FOREVER, &block) if block_given? if @transposed && length > 0 count.times do process_all do |_index, posn| block.call(@array_data[posn]) end end nil else @array_data.cycle(count.to_i, &block) end else self.to_enum(:cycle, count) end end |
#dimensions ⇒ Object
The number of dimensions in this array.
50 51 52 |
# File 'lib/flex_array.rb', line 50 def dimensions @array_specs.spec_dimensions end |
#dup ⇒ Object
Create a duplicate of this array.
20 21 22 23 24 25 |
# File 'lib/flex_array/flex_array_new.rb', line 20 def dup other = self.shallow_dup other.array_specs = @array_specs.dup other.array_data = @array_data.dup other end |
#each(&block) ⇒ Object
Process the standard each operator.
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/flex_array/flex_array_each.rb', line 45 def each(&block) if block_given? if @transposed process_all {|_index, posn| block.call(@array_data[posn])} else @array_data.each(&block) end self else self.to_enum(:each) end end |
#each_with_index(&block) ⇒ Object
Process the standard each_with_index operator.
72 73 74 75 76 77 78 79 |
# File 'lib/flex_array/flex_array_each.rb', line 72 def each_with_index(&block) if block_given? process_all {|index, posn| block.call(@array_data[posn], index)} self else self.to_enum(:each_with_index) end end |
#empty? ⇒ Boolean
Is this flex array empty?
78 79 80 |
# File 'lib/flex_array.rb', line 78 def empty? length == 0 end |
#find_index(value = nil, &block) ⇒ Object
The flex array version of find_index. This returns the coordinates of the first object that matches the search object or is flagged true by the search block.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/flex_array/flex_array_each.rb', line 175 def find_index(value = nil, &block) blk = get_find_block(value, &block) if blk process_all do |index, posn| if blk.call(@array_data[posn]) return index end end nil else self.to_enum(:find_index) end end |
#find_indexes(value = nil, &block) ⇒ Object
The improved flex array version of find_index. This returns the coordinates of objects that match the search object or are flagged true by the search block.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/flex_array/flex_array_each.rb', line 214 def find_indexes(value = nil, &block) blk, result = get_find_block(value, &block), [] if blk process_all do |index, posn| if blk.call(@array_data[posn]) result << index.dup end end result else self.to_enum(:find_indexes) end end |
#flatten_collect ⇒ Object
117 |
# File 'lib/flex_array/flex_array_each.rb', line 117 alias_method :flatten_collect, :collect |
#length ⇒ Object Also known as: size
The total number of elements in this array.
43 44 45 |
# File 'lib/flex_array.rb', line 43 def length @array_specs.spec_count end |
#limits ⇒ Object
Get the limits of the subscripts of the flex array.
58 59 60 |
# File 'lib/flex_array.rb', line 58 def limits @array_specs.collect {|spec| spec.range } end |
#reshape(array_specs) ⇒ Object
Return a copy of this flex array, recast in a new shape, dropping or repeating data elements as required.
6 7 8 9 |
# File 'lib/flex_array/flex_array_reshape.rb', line 6 def reshape(array_specs) iterator = @array_data.cycle FlexArray.new(array_specs) {iterator.next} end |
#reshape!(array_specs) ⇒ Object
Recast this flex array in a new shape, dropping or repeating data elements as required.
13 14 15 16 17 |
# File 'lib/flex_array/flex_array_reshape.rb', line 13 def reshape!(array_specs) temp = self.reshape(array_specs) @array_specs, @array_data = temp.array_specs, temp.array_data self end |
#select_collect(indexes, &block) ⇒ Object
The flex array version of collect that accepts an optional set of indexes to select the data being collected into a flex array.
127 128 129 130 |
# File 'lib/flex_array/flex_array_each.rb', line 127 def select_collect(indexes, &block) result = self.dup result.select_collect!(indexes, &block) end |
#select_collect!(indexes, &block) ⇒ Object
The enhanced flex array version of collect! that accepts a set of indexes to select the data being collected.
162 163 164 165 166 167 168 169 170 |
# File 'lib/flex_array/flex_array_each.rb', line 162 def select_collect!(indexes, &block) fail ArgumentError, "A block is required." unless block_given? validate_index_count(indexes) process_indexes(indexes) {|_index, posn| @array_data[posn] = block.call(@array_data[posn])} self end |
#select_cycle(indexes, count = FOREVER, &block) ⇒ Object
Retrieve data from a subset of the flex array endlessly repeating as needed.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/flex_array/flex_array_each.rb', line 26 def select_cycle(indexes, count = FOREVER, &block) validate_index_count(indexes) if block_given? unless empty? count.times do process_indexes(indexes) do |_index, posn| block.call(@array_data[posn]) end end end nil else self.to_enum(:select_cycle, indexes, count) end end |
#select_each(indexes, &block) ⇒ Object
Process the enhanced select_each operator.
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/flex_array/flex_array_each.rb', line 60 def select_each(indexes, &block) validate_index_count(indexes) if block_given? process_indexes(indexes) {|_index, posn| block.call(@array_data[posn])} self else self.to_enum(:select_each, indexes) end end |
#select_each_with_index(indexes, &block) ⇒ Object
Process the enhanced select_each_with_index operator.
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/flex_array/flex_array_each.rb', line 82 def select_each_with_index(indexes, &block) validate_index_count(indexes) if block_given? process_indexes(indexes) {|index, posn| block.call(@array_data[posn], index)} self else self.to_enum(:select_each_with_index, indexes) end end |
#select_find_index(indexes, value = nil, &block) ⇒ Object
The enhanced flex array version of find_index. This returns the coordinates of the first object that matches the search object or is flagged true by the search block.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/flex_array/flex_array_each.rb', line 194 def select_find_index(indexes, value = nil, &block) validate_index_count(indexes) blk = get_find_block(value, &block) if blk process_indexes(indexes) do |index, posn| if blk.call(@array_data[posn]) return index end end nil else self.to_enum(:select_find_index, indexes) end end |
#select_find_indexes(indexes, value = nil, &block) ⇒ Object
The enhanced and improved flex array version of find_index. This returns the coordinates of objects that match the search object or are flagged true by the search block.
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/flex_array/flex_array_each.rb', line 233 def select_find_indexes(indexes, value = nil, &block) validate_index_count(indexes) blk, result = get_find_block(value, &block), [] if blk process_indexes(indexes) do |index, posn| if blk.call(@array_data[posn]) result << index.dup end end result else self.to_enum(:select_find_index, indexes) end end |
#select_flatten_collect(indexes, &block) ⇒ Object
The flex array version of collect that accepts an optional set of indexes to select the data being collected into a standard array.
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/flex_array/flex_array_each.rb', line 134 def select_flatten_collect(indexes, &block) validate_index_count(indexes) if block_given? result = [] process_indexes(indexes) {|_index, posn| result << block.call(@array_data[posn])} result else self.to_enum(:select_collect, indexes) end end |
#shallow_dup ⇒ Object
17 |
# File 'lib/flex_array/flex_array_new.rb', line 17 alias_method :shallow_dup, :dup |
#to_a ⇒ Object
Convert the flex array to a simple array. Contained arrays are not affected.
20 21 22 23 24 25 26 27 |
# File 'lib/flex_array/flex_array_reshape.rb', line 20 def to_a if @transposed fetch = self.cycle Array.new(@array_data.length) { fetch.next } else @array_data.dup end end |
#to_flex_array ⇒ Object
Return this flex array as a flex array!
63 64 65 |
# File 'lib/flex_array.rb', line 63 def to_flex_array self end |
#transpose(dim_a, dim_b) ⇒ Object
Return a reference to this array’s data with the specified dimensions transposed. This may change the “shape” of the array if the transposed dimensions were of different limits.
17 18 19 |
# File 'lib/flex_array/flex_array_transpose.rb', line 17 def transpose(dim_a, dim_b) FlexArray.new_from_array(self).transpose!(dim_a, dim_b) end |
#transpose!(dim_a, dim_b) ⇒ Object
Transpose the specified dimensions. This may change the “shape” of the array if the transposed dimensions were of different limits.
6 7 8 9 10 11 12 |
# File 'lib/flex_array/flex_array_transpose.rb', line 6 def transpose!(dim_a, dim_b) validate_dimension(dim_a) validate_dimension(dim_b) @array_specs[dim_a], @array_specs[dim_b] = @array_specs[dim_b], @array_specs[dim_a] @transposed = @array_specs.transposed? self end |