Class: MapWithIndifferentAccess::List
- Inherits:
-
Object
- Object
- MapWithIndifferentAccess::List
- Extended by:
- Forwardable
- Includes:
- WrapsCollection
- Defined in:
- lib/map_with_indifferent_access/list.rb
Instance Attribute Summary collapse
Attributes included from WrapsCollection
Class Method Summary collapse
-
.try_convert(from_obj) ⇒ List?
Try to convert
from_objinto a List. -
.try_deconstruct(obj) ⇒ Array?
Try to convert
obj, which might be a List into anArray.
Instance Method Summary collapse
-
#&(other) ⇒ List
Set Intersection.
-
#*(n_copies_or_separator) ⇒ Object
Repetition.
-
#+(other) ⇒ List
Concatenation.
-
#-(other) ⇒ List
Difference.
-
#<<(value) ⇒ List
Append.
-
#<=>(other) ⇒ 1, ...
Comparison.
-
#==(other) ⇒ Boolean
Equality.
-
#[] ⇒ Object
Returns the element at index, or returns a subarray starting at the start index and continuing for length elements, or returns a subarray specified by range of indices.
-
#[]=(index, length_or_value, *maybe_value) ⇒ Object
Element Assignment — Sets the element at index, or replaces a subarray from the start index for length elements, or replaces a subarray specified by the range of indices.
-
#assoc(value) ⇒ List?
Searches through elements of the target
Listthat are also externally represented asLists, comparing the first item in each of those withvalueusing #==. -
#at(index) ⇒ Object
Returns the externalization of the element at
index. -
#bsearch ⇒ Object
Works identically to
Array#bsearchexcept that externalized values are passed to the block, and the externalized result is returned. -
#collect! {|extern_item| ... } ⇒ List, Enumerable
Invokes the given block once for each externalized item from the target
List, replacing the element with the internalization of the value returned by the block. -
#combination(n) ⇒ Object
Yields every combination of length n of elements from the target
Listin the form of aListand then returns the targetListitself. -
#compact ⇒ List
Returns a copy of the target
Listwith allnilitems removed. -
#compact! ⇒ List?
Removes
nilelements from the targetList. -
#concat(other) ⇒ List
Appends elements of
other(aListor otherArray-like object) to the targetList. -
#delete(obj) ⇒ Object
Deletes all items from self, the externalizations of which are equal to the externalization of
obj. -
#delete_at(index) ⇒ Object?
Deletes the element at the specified
index, returning the externalization of that element, ornilif the index is out of range. -
#each ⇒ Object
Calls the given block once for each item in the target's #inner_array, passing the externalization of the item to the block.
-
#fetch(index, *args) ⇒ Object
Tries to retrieve the element at position
index, but raises anIndexErrorexception or uses a default value when an invalid index is referenced. - #first ⇒ Object
-
#initialize(basis = []) ⇒ List
constructor
Initializes a new instance of List that encapsulates a new empty
Arrayor theArraycoerced from the givenbasis. -
#insert(index, *values) ⇒ List
Inserts the given values before the element with the given index.
-
#join(separator = $,) ⇒ String
Returns a string consisting of
String-converted item values from the targetListseparated by theseparatorstring. - #last ⇒ Object
-
#pop(*maybe_n) ⇒ Object
Removes and returns the last element or last
nelements of the array. -
#push(*values) ⇒ List
Append.
-
#rassoc(value) ⇒ List?
Searches through elements of the target
Listthat are also externally represented asLists, comparing the second item in each of those withvalueusing #==. -
#shift(*maybe_n) ⇒ Object
Removes and returns the first element or first
nelements of the array, shifting all of the other elements downward. -
#to_a ⇒ Object
Alias for WrapsCollection#inner_collection.
-
#uniq ⇒ List
Returns a new instance with duplicate items omitted.
-
#uniq! ⇒ List?
Deletes duplicate items from the target's #inner_array, leaving only unique items remaining.
-
#unshift(*values) ⇒ List
Prepends objects to the front of the list, moving other elements upwards.
-
#values_at(*indexes) ⇒ Object
Returns a List containing the elements in self corresponding to the given selector(s).
-
#|(other) ⇒ List
Set Union.
Methods included from WrapsCollection
#_frozen?, #clear, #empty?, #eql?, #freeze, #frozen?, #hash, #length, #size, #taint, #tainted?, #trust, #untaint, #untrust, #untrusted?
Constructor Details
#initialize(basis = []) ⇒ List
Initializes a new instance of MapWithIndifferentAccess::List that encapsulates a
new empty Array or the Array coerced from the given
basis.
When a MapWithIndifferentAccess::List is given as a basis, this results on the
given and new instances sharing the same #inner_array.
There is no obvious reason to do that on purpose, but there
is also no particular harm in allowing it to happen.
77 78 79 80 81 82 83 |
# File 'lib/map_with_indifferent_access/list.rb', line 77 def initialize(basis = []) use_basis = basis use_basis = basis.inner_array if self.class === basis use_basis = ::Array.try_convert( use_basis ) raise ArgumentError, "Could not convert #{basis.inspect} into an ::Array" unless use_basis @inner_collection = use_basis end |
Instance Attribute Details
#inner_array=(value) ⇒ Array
Alias for WrapsCollection#inner_collection. The encapsulated Array
instance.
55 |
# File 'lib/map_with_indifferent_access/list.rb', line 55 alias inner_array inner_collection |
Class Method Details
.try_convert(from_obj) ⇒ List?
Try to convert from_obj into a MapWithIndifferentAccess::List.
22 23 24 25 26 27 28 29 |
# File 'lib/map_with_indifferent_access/list.rb', line 22 def self.try_convert(from_obj) if self === from_obj from_obj else array = ::Array.try_convert( from_obj ) new( array ) if array end end |
.try_deconstruct(obj) ⇒ Array?
Try to convert obj, which might be a MapWithIndifferentAccess::List into an
Array.
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/map_with_indifferent_access/list.rb', line 39 def self.try_deconstruct(obj) if self === obj obj.inner_array elsif obj.respond_to?(:to_ary ) a = obj.to_ary ::Array === a ? a : nil else nil end end |
Instance Method Details
#&(other) ⇒ List
Set Intersection. Returns a new MapWithIndifferentAccess::List containing
elements common to the target MapWithIndifferentAccess::List and other (a
List or other Array-like object), excluding any
duplicate items. The order is preserved from the
original list.
It compares elements using their #hash and #eql?
methods for efficiency.
Note that this does not recongnize items of Map type as
equal just because they are equal by #==, which can be
the case when they have equivalent keys that differ by
String/Symbol type. You might therefore wish to call
#& for lists that have first had their keys
deeply-stringified or deeply-symbolized.
|
|
# File 'lib/map_with_indifferent_access/list.rb', line 420
|
#*(n_copies) ⇒ Map #*(separator) ⇒ String
Repetition.
529 530 531 532 533 |
# File 'lib/map_with_indifferent_access/list.rb', line 529 def *(n_copies_or_separator) result = inner_array * n_copies_or_separator result = List.new( result ) if Array === result result end |
#+(other) ⇒ List
Concatenation. Returns a new MapWithIndifferentAccess::List built by
concatenating other (a List or other Array-like
object) to the target List.
|
|
# File 'lib/map_with_indifferent_access/list.rb', line 459
|
#-(other) ⇒ List
Difference. Returns a new MapWithIndifferentAccess::List that is a copy of the
original, removing any items that also appear in
other (a List or other Array-like object). The
order is preserved from the original List.
It compares elements using their #hash and #eql?
methods for efficiency.
Note that this does not recongnize items of Map type as
equal just because they are equal by #==, which can be
the case when they have equivalent keys that differ by
String/Symbol type. You might therefore wish to call
#- for lists that have first had their keys
deeply-stringified or deeply-symbolized.
488 489 490 491 492 493 494 495 496 497 498 |
# File 'lib/map_with_indifferent_access/list.rb', line 488 %w( & | + - ).each do |method_name| class_eval <<-EOS, __FILE__, __LINE__ + 1 def #{method_name}(other) other = self.class.try_deconstruct( other ) || other inner_result = inner_array.#{method_name}(other) List.new( inner_result ) end EOS end |
#<<(value) ⇒ List
Append. Pushes the given object on to the end of the list. Returns the array itself, so several appends may be chained together.
Internalizes the given onject before appending it to the target's #inner_array.
213 214 215 216 217 |
# File 'lib/map_with_indifferent_access/list.rb', line 213 def <<(value) value = Values << value inner_array << value self end |
#<=>(other) ⇒ 1, ...
Comparison. Returns an integer (-1, 0, or +1) if this
List is less than, equal to, or greater than other, and
other is a List or other Array-like object that can
be coerced to a List.
Each externaized item in the target List is compared to
the corresponding externalized item in other (using the
<=> operator). As soon as a comparison is non zero (i.e.
the two corresponding elements are not equal), that result
is returned for the whole array comparison.
If all the elements are equal, then the result is based on
a comparison of the list lengths. Thus, two Lists are
"equal" according to #<=> if, and only if, they have the
same length and the value of each element is equal to the
value of the corresponding element in the other list.
nil is returned if other is not a List or Arraylike
object or if the comparison of two elements returns nil.
680 681 682 683 684 685 686 687 |
# File 'lib/map_with_indifferent_access/list.rb', line 680 def <=>(other) return nil unless \ List === other || ( other.respond_to?(:to_ary ) && other.respond_to?(:length ) ) other = Values >> other rel_order( other ) end |
#==(other) ⇒ Boolean
Equality. The target is equal to the given Array-like
object if both contain the same number of elements, and
externalizations of corresponding items in itself and the
given object are equal according to #==.
643 644 645 646 647 648 649 650 651 652 653 654 |
# File 'lib/map_with_indifferent_access/list.rb', line 643 def ==(other) same_class = self.class === other return false unless same_class || other.respond_to?(:to_ary ) # Optimizations return true if equal?( other ) return true if same_class && inner_array == other.inner_array return false unless length == other.length zip( other ).all? { |(v,other_v)| v == Values >> other_v } end |
#[](index) ⇒ Object #[](start, length) ⇒ List #[](range) ⇒ List #slice(index) ⇒ Object #slice(start, length) ⇒ List #slice(range) ⇒ List
Returns the element at index, or returns a subarray starting at the start index and continuing for length elements, or returns a subarray specified by range of indices.
Externalizes the result before returning it.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/map_with_indifferent_access/list.rb', line 172 ['[]', 'slice'].each do |method_name| class_eval <<-EOS, __FILE__, __LINE__ + 1 def #{method_name}(index, *maybe_length) arg_count = 1 + maybe_length.length unless (1..2) === arg_count raise ArgumentError, "wrong number of arguments (\#{arg_count} for 1..2)" end if !maybe_length.empty? || Range === index value_array = inner_array.#{method_name}( index, *maybe_length ) value_array.map!{ |v| Values >> v } List.new( value_array ) else value = inner_array.#{method_name}( index ) Values >> value end end EOS end |
#[]=(index, value) ⇒ Object #[]=(start, length, array_or_value) ⇒ Object #[]=(range, array_or_value) ⇒ Object
Element Assignment — Sets the element at index, or replaces a subarray from the start index for length elements, or replaces a subarray specified by the range of indices.
The given object or array is internalized befor being ussed for assignment into the #inner_array.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/map_with_indifferent_access/list.rb', line 110 def []=(index, length_or_value, *maybe_value) arg_count = 2 + maybe_value.length unless (2..3) === arg_count raise ArgumentError, "wrong number of arguments (#{arg_count} for 2..3)" end if maybe_value.empty? maybe_length = [] value_or_values = length_or_value else maybe_length = [length_or_value] value_or_values = maybe_value.first end if ( ( !maybe_length.empty? || Range === index ) && ( value_array = List.try_deconstruct( value_or_values ) ) ) value_array = value_array.map{ |v| Values << v } inner_array[ index, *maybe_length ] = value_array else value = Values << value_or_values inner_array[ index, *maybe_length ] = value end end |
#assoc(value) ⇒ List?
Searches through elements of the target List that are
also externally represented as Lists, comparing the
first item in each of those with value using #==.
Returns the first item from the target that matches (is
the first associated List) or nil of no match is found.
|
|
# File 'lib/map_with_indifferent_access/list.rb', line 708
|
#at(index) ⇒ Object
Returns the externalization of the element at index. A
negative index counts from the end of the list. Returns
nil if the index is out of range.
199 200 201 202 |
# File 'lib/map_with_indifferent_access/list.rb', line 199 def at(index) item = inner_array.at( index ) Values >> item end |
#bsearch {|x| ... } ⇒ Object? #bsearch ⇒ Enumerator
Works identically to Array#bsearch except that
externalized values are passed to the block, and the
externalized result is returned.
759 760 761 762 763 |
# File 'lib/map_with_indifferent_access/list.rb', line 759 def bsearch return to_enum(:bsearch) unless block_given? inner_result = inner_array.bsearch{ |x| yield Values >> x } Values >> inner_result end |
#collect! ⇒ List, Enumerable #map! ⇒ List, Enumerable
Invokes the given block once for each externalized item
from the target List, replacing the element with the
internalization of the value returned by the block.
If no block is given, returns an Enumerator instead.
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 |
# File 'lib/map_with_indifferent_access/list.rb', line 780 %w(collect! map!).each do |method_name| class_eval <<-EOS, __FILE__, __LINE__ + 1 def #{method_name} return to_enum( :#{method_name} ) unless block_given? inner_array.#{method_name}{ |item| item = Values >> item mapped_outer = yield( item ) Values << mapped_outer } self end EOS end |
#combination(n) {|combination| ... } ⇒ List #combination(n) ⇒ Enumerator
Yields every combination of length n of elements from the
target List in the form of a List and then returns the
target List itself.
Makes no guarantees about the order in which the combinations are yielded.
If no block is given, an Enumerator is returned instead.
814 815 816 817 818 819 820 821 |
# File 'lib/map_with_indifferent_access/list.rb', line 814 def combination(n) return to_enum( :combination, n ) unless block_given? inner_array.combination n do |inner_combos| yield List.new( inner_combos ) end self end |
#compact ⇒ List
Returns a copy of the target List with all nil items
removed.
841 842 843 844 845 |
# File 'lib/map_with_indifferent_access/list.rb', line 841 def compact result = dup result.compact! result end |
#compact! ⇒ List?
Removes nil elements from the target List.
Returns nil if no changes were made. Otherwise returns
the List.
831 832 833 |
# File 'lib/map_with_indifferent_access/list.rb', line 831 def compact! inner_array.compact! && self end |
#concat(other) ⇒ List
Appends elements of other (a List or other
Array-like object) to the target List.
280 281 282 283 284 |
# File 'lib/map_with_indifferent_access/list.rb', line 280 def concat(other) other = self.class.try_deconstruct(other) || other inner_array.concat other self end |
#delete(obj) ⇒ Object #delete(obj) { ... } ⇒ Object
Deletes all items from self, the externalizations of which
are equal to the externalization of obj.
Returns the externalization of the last deleted item if applicable.
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/map_with_indifferent_access/list.rb', line 550 def delete(obj) obj = Values >> obj removed_items = false result = nil inner_array.delete_if{ |v| v = Values >> v if v == obj result = v removed_items = true true end } if !removed_items && block_given? result = Values >> yield( obj ) end result end |
#delete_at(index) ⇒ Object?
Deletes the element at the specified index, returning the
externalization of that element, or nil if the index is
out of range.
415 416 417 418 |
# File 'lib/map_with_indifferent_access/list.rb', line 415 def delete_at(index) inner_result = inner_array.delete_at( index ) Values >> inner_result end |
#each {|item| ... } ⇒ List #each ⇒ Enumerator
Calls the given block once for each item in the target's #inner_array, passing the externalization of the item to the block.
701 702 703 704 705 706 |
# File 'lib/map_with_indifferent_access/list.rb', line 701 def each inner_array.each do |item| item = Values >> item yield item end end |
#fetch(index) ⇒ Object #fetch(index, default) ⇒ Object #fetch(index) {|index| ... } ⇒ Object
Tries to retrieve the element at position index, but
raises an IndexError exception or uses a default value
when an invalid index is referenced.
Returns the externalization of the retrieved value.
323 324 325 326 327 328 329 330 331 |
# File 'lib/map_with_indifferent_access/list.rb', line 323 def fetch(index, *args) item = if block_given? inner_array.fetch( index, *args ){ |idx| yield idx } else inner_array.fetch( index, *args ) end Values >> item end |
#first ⇒ Object
7 8 9 |
# File 'lib/map_with_indifferent_access/list.rb', line 7 def first self.at(0) end |
#insert(index, *values) ⇒ List
Inserts the given values before the element with the given index.
Internalizes the values before inserting them into the target's #inner_array.
Negative indices count backwards from the end of the array, where -1 is the last element. If a negative index is used, the given values will be inserted after that element, so using an index of -1 will insert the values at the end of the list.
267 268 269 270 271 |
# File 'lib/map_with_indifferent_access/list.rb', line 267 def insert(index, *values) values.map!{ |v| Values << v } inner_array.insert(index, *values) self end |
#join(separator = $,) ⇒ String
Returns a string consisting of String-converted item
values from the target List separated by the
separator string. If no separator or nil is given,
uses the value of $, as the separator. Treats a nil
$, value as a blank string.
The items are not externalized before being converted to
Strings, so my_map.join is exactly equivalent to
my_map.inner_array.join.
515 |
# File 'lib/map_with_indifferent_access/list.rb', line 515 def_delegator :inner_array, :join |
#last ⇒ Object
11 12 13 |
# File 'lib/map_with_indifferent_access/list.rb', line 11 def last self.at(-1) end |
#pop ⇒ Object? #pop(n) ⇒ MapWithIndifferentAccess::List
Removes and returns the last element or last n elements
of the array.
Returns the externalization of the removed element or array of elements
See #push for the opposite effect.
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/map_with_indifferent_access/list.rb', line 387 %w(shift pop).each do |method_name| class_eval <<-EOS, __FILE__, __LINE__ + 1 def #{method_name}(*maybe_n) arg_count = maybe_n.length unless (0..1) === arg_count raise ArgumentError, "wrong number of arguments (\#{arg_count} for 0..1)" end if maybe_n.empty? Values >> inner_array.#{method_name} else inner_result = inner_array.#{method_name}( *maybe_n ) List.new( inner_result ) end end EOS end |
#push(*values) ⇒ List
Append. Pushes the given object(s) on to the end of the list. Returns the array itself, so several appends may be chained together.
Internalizes each given object before appending it to the target's #inner_array.
230 231 232 233 234 |
# File 'lib/map_with_indifferent_access/list.rb', line 230 def push(*values) values.map!{ |v| Values << v } inner_array.push *values self end |
#rassoc(value) ⇒ List?
Searches through elements of the target List that are
also externally represented as Lists, comparing the
second item in each of those with value using #==.
Returns the first item from the target that matches (is
the first associated List) or nil of no match is found.
734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
# File 'lib/map_with_indifferent_access/list.rb', line 734 [ ['assoc', 0 ], ['rassoc', 1 ] ].each do |(method_name,search_col)| class_eval <<-EOS, __FILE__, __LINE__ def #{method_name}(value) result = nil each do |item| next unless List === item && item.length > #{search_col} result = item if item[#{search_col}] == value end result end EOS end |
#shift ⇒ Object? #shift(n) ⇒ List
Removes and returns the first element or first n
elements of the array, shifting all of the other elements
downward.
Returns the externalization of the removed element or array of elements
See #unshift for the opposite effect.
|
|
# File 'lib/map_with_indifferent_access/list.rb', line 333
|
#to_a ⇒ Object
Alias for WrapsCollection#inner_collection. Returns the
encapsulated Array instance.
|
|
# File 'lib/map_with_indifferent_access/list.rb', line 57
|
#uniq ⇒ List
Returns a new instance with duplicate items omitted.
Items are considered equal if their #hash values are
equal and comparison using #eql? returns true.
If a block is given, then externalized items are passed to the block, and the return values from the block will be used for dupliacte-check comparison.
Note that items externally represented as Maps that are
equal according to Map#== will not necessarily be
identified as duplicates since they can still differ
according to Map#eql if their encapsulated Hash
objects are unequal due to key String/Symbol type
differences. You might therefore want to ensure that the
target List has been deeply stringified or symbolized
before calling #uniq! on it.
588 589 590 591 592 593 594 595 596 |
# File 'lib/map_with_indifferent_access/list.rb', line 588 def uniq result = dup if block_given? result.uniq!{ |item| yield( item ) } else result.uniq! end result end |
#uniq! ⇒ List?
Deletes duplicate items from the target's #inner_array,
leaving only unique items remaining. Items are considered
equal if their #hash values are equal and comparison
using #eql? returns true.
Returns the target List if any duplicates were found and
removed. Otherwise, returns nil.
If a block is given, then externalized items are passed to the block, and the return values from the block will be used for dupliacte-check comparison.
Note that items externally represented as Maps that are
equal according to Map#== will not necessarily be
identified as duplicates since they can still differ
according to Map#eql if their encapsulated Hash
objects are unequal due to key String/Symbol type
differences. You might therefore want to ensure that the
target List has been deeply stringified or symbolized
before calling #uniq on it.
622 623 624 625 626 627 628 629 630 631 632 633 |
# File 'lib/map_with_indifferent_access/list.rb', line 622 def uniq! inner_result = if block_given? inner_array.uniq!{ |item| yield( Values >> item ) } else inner_array.uniq! end inner_result && self end |
#unshift(*values) ⇒ List
Prepends objects to the front of the list, moving other elements upwards.
Internalizes each value before prepending it to the target's #inner_array.
See also #shift for the opposite effect.
247 248 249 250 251 |
# File 'lib/map_with_indifferent_access/list.rb', line 247 def unshift(*values) values.map!{ |v| Values << v } inner_array.unshift *values self end |
#values_at(*indexes) ⇒ Object
Returns a MapWithIndifferentAccess::List containing the elements in self corresponding to the given selector(s).
The selectors may be either Integer indices or
Ranges.
293 294 295 296 |
# File 'lib/map_with_indifferent_access/list.rb', line 293 def values_at(*indexes) inner_result = inner_array.values_at( *indexes ) Values >> inner_result end |
#|(other) ⇒ List
Set Union. Returns a new MapWithIndifferentAccess::List by joining the target
List with other (a List or other Array-like
object), excluding any duplicates and preserving the
order from the original List.
It compares elements using their #hash and #eql?
methods for efficiency.
Note that this does not recongnize items of Map type as
equal just because they are equal by #==, which can be
the case when they have equivalent keys that differ by
String/Symbol type. You might therefore wish to call
#| for lists that have first had their keys
deeply-stringified or deeply-symbolized.
|
|
# File 'lib/map_with_indifferent_access/list.rb', line 440
|