Module: Indexable
- Included in:
- Array
- Defined in:
- lib/core/facets/indexable.rb
Overview
Indexable
Indexable is a mixin that provides index based methods, working soley with four methods: #index, #slice, #splice and #size.
These methods work in harmony. Where #index returns a position of a given element, #slice returns elements for given positions. #splice is like #slice but replaces the given position with new values. This mehtod is not part of ruby core, but it generally just an alias for #[]=, just as #slice is an alias of #[]. #size of course simply returns the total length of the indexable object.
NOTE: To test the folowing methods Indexable needs to be included into Array and array must have #splice defined.
require 'facets/array/splice'
class ::Array
include Indexable
end
CREDIT: Thomas Sawyer
Instance Method Summary collapse
-
#body ⇒ Object
Returns an array of the first element upto, but not including, the last element.
-
#ends ⇒ Object
A shorting of “ends at”, returns the last index of the indexable object.
-
#first(n = 1) ⇒ Object
Returns first n elements.
-
#first! ⇒ Object
Remove and return the first element.
-
#first=(x) ⇒ Object
Change the first element.
-
#foot ⇒ Object
Like #last, returning the last element in an array.
-
#from(i) ⇒ Object
Returns last n elements.
-
#head ⇒ Object
Like #first but returns the first element in a new array.
-
#index(obj = nil, &block) ⇒ Object
(also: #index_of)
Returns the index of the first element equal to the given object or satisfying the block condition.
-
#last(n = 1) ⇒ Object
Returns last n elements.
-
#last! ⇒ Object
Remove and return the last element.
-
#last=(x) ⇒ Object
Change the last element.
-
#mid(offset = 0) ⇒ Object
Returns the middle element of an array, or the element offset from middle if the parameter is given.
-
#middle(birth = 0) ⇒ Object
Returns an Array of the middle element(s) of an array.
-
#pos(i) ⇒ Object
Returns the positive ordinal index given a cardinal position, 1 to n or -n to -1.
-
#range(a = nil, z = -1)) ⇒ Object
Returns the index range between two elements.
-
#tail ⇒ Object
Returns an array from second element to last element.
-
#thru(from, to = nil) ⇒ Object
Fetch values from a start index thru an end index.
Instance Method Details
#body ⇒ Object
Returns an array of the first element upto, but not including, the last element.
[1,2,3].body #=> [1,2]
– Better name for this? (bulk, perhaps?) ++
63 64 65 |
# File 'lib/core/facets/indexable.rb', line 63 def body slice(0,size-1) end |
#ends ⇒ Object
A shorting of “ends at”, returns the last index of the indexable object. Returns nil if there are no elements.
[1,2,3,4,5].ends #=> 4
This nearly equivalent to size - 1.
212 213 214 215 |
# File 'lib/core/facets/indexable.rb', line 212 def ends return nil if size == 0 size - 1 end |
#first(n = 1) ⇒ Object
Returns first n elements.
%w{H e l l o}.first(3) #=> %w{H e l}
150 151 152 |
# File 'lib/core/facets/indexable.rb', line 150 def first(n=1) slice(0, n.to_i) end |
#first! ⇒ Object
Remove and return the first element.
a = [1,2,3]
a.first! #=> 1
a #=> [2,3]
190 191 192 |
# File 'lib/core/facets/indexable.rb', line 190 def first! splice(0) end |
#first=(x) ⇒ Object
Change the first element.
a = ["a","y","z"]
a.first = "x"
a #=> ["x","y","z"]
170 171 172 |
# File 'lib/core/facets/indexable.rb', line 170 def first=(x) splice(0,x) end |
#foot ⇒ Object
Like #last, returning the last element in an array.
[1,2,3].foot #=> [3]
50 51 52 |
# File 'lib/core/facets/indexable.rb', line 50 def foot slice(-1,1) end |
#from(i) ⇒ Object
Returns last n elements.
%w{W o r l d}.from(3) #=> %w{l d}
132 133 134 135 |
# File 'lib/core/facets/indexable.rb', line 132 def from(i) return self if i >= size slice(i, size - i) #slice(-n..-1) end |
#head ⇒ Object
Like #first but returns the first element in a new array.
[1,2,3].head #=> [1]
33 34 35 |
# File 'lib/core/facets/indexable.rb', line 33 def head slice(0,1) end |
#index(obj = nil, &block) ⇒ Object Also known as: index_of
Returns the index of the first element equal to the given object or satisfying the block condition.
[1,2,3,4].index{ |e| e == 3 } #=> 2
[1,2,3,4].index{ |e| e > 3 } #=> 3
237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/core/facets/indexable.rb', line 237 def index(obj=nil, &block) if block_given? size.times do |i| return i if yield(slice(i)) end else size.times do |i| return i if obj == slice(i) end end nil end |
#last(n = 1) ⇒ Object
Returns last n elements.
%w{H e l l o}.last(3) #=> %w{l l o}
158 159 160 161 162 |
# File 'lib/core/facets/indexable.rb', line 158 def last(n=1) n = n.to_i return self if n > size slice(-n, n) #slice(-n..-1) end |
#last! ⇒ Object
Remove and return the last element.
a = [1,2,3]
a.last! #=> 3
a #=> [1,2]
200 201 202 |
# File 'lib/core/facets/indexable.rb', line 200 def last! splice(-1) end |
#last=(x) ⇒ Object
Change the last element.
a = [1,2,5]
a.last = 3
a #=> [1,2,3]
180 181 182 |
# File 'lib/core/facets/indexable.rb', line 180 def last=(x) splice(-1,x) end |
#mid(offset = 0) ⇒ Object
Returns the middle element of an array, or the element offset from middle if the parameter is given. Even-sized arrays, not having an exact middle, return the middle-right element.
[1,2,3,4,5].mid #=> 3
[1,2,3,4,5,6].mid #=> 4
[1,2,3,4,5,6].mid(-1) #=> 3
[1,2,3,4,5,6].mid(-2) #=> 2
[1,2,3,4,5,6].mid(1) #=> 5
In other words, If there are an even number of elements the higher-indexed of the two center elements is indexed as orgin (0).
81 82 83 |
# File 'lib/core/facets/indexable.rb', line 81 def mid(offset=0) slice((size / 2) + offset) end |
#middle(birth = 0) ⇒ Object
Returns an Array of the middle element(s) of an array. Even-sized arrays, not having an exact middle, return a two-element array of the two middle elements.
[1,2,3,4,5].middle #=> [3]
[1,2,3,4,5,6].middle #=> [3,4]
A birth
can be give to widen the middle on either side.
[1,2,3,4,5].middle(1) #=> [2,3,4]
[1,2,3,4,5,6].middle(1) #=> [2,3,4,5]
In contrast to #mid which utilizes an offset.
99 100 101 102 103 104 105 106 |
# File 'lib/core/facets/indexable.rb', line 99 def middle(birth=0) i = size / 2 - birth if size % 2 == 0 slice(i - 1, 2 + (2 * birth)) else slice(i, 1 + (2 * birth)) end end |
#pos(i) ⇒ Object
Returns the positive ordinal index given a cardinal position, 1 to n or -n to -1.
[1,2,3,4,5].pos(1) #=> 0
[1,2,3,4,5].pos(-1) #=> 4
223 224 225 226 227 228 229 |
# File 'lib/core/facets/indexable.rb', line 223 def pos(i) if i > 0 return i - 1 else size + i end end |
#range(a = nil, z = -1)) ⇒ Object
Returns the index range between two elements. If no elements are given, returns the range from first to last.
['a','b','c','d'].range #=> (0..3)
['a','b','c','d'].range('b','d') #=> (1..3)
261 262 263 264 265 266 267 |
# File 'lib/core/facets/indexable.rb', line 261 def range(a=nil,z=-1) if a index(a)..index(z) else (0..(size-1)) end end |
#tail ⇒ Object
Returns an array from second element to last element.
[1,2,3].tail #=> [2,3]
41 42 43 |
# File 'lib/core/facets/indexable.rb', line 41 def tail slice(1,length-1) end |
#thru(from, to = nil) ⇒ Object
Fetch values from a start index thru an end index.
[1,2,3,4,5].thru(0,2) #=> [1,2,3]
[1,2,3,4,5].thru(2,4) #=> [3,4,5]
[1,2,3,4,5].thru(2) #=> [1,2,3]
[1,2,3,4,5].thru(4) #=> [1,2,3,4,5]
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/core/facets/indexable.rb', line 116 def thru(from, to=nil) from, to = 0, from unless to to = size - 1 if to >= size a = [] i = from while i <= to a << slice(i) i += 1 end a end |