4 # ary.uniq! -> ary or nil
5 # ary.uniq! { |item| ... } -> ary or nil
7 # Removes duplicate elements from +self+.
8 # Returns <code>nil</code> if no changes are made (that is, no
9 # duplicates are found).
11 # a = [ "a", "a", "b", "b", "c" ]
12 # a.uniq! #=> ["a", "b", "c"]
13 # b = [ "a", "b", "c" ]
15 # c = [["student","sam"], ["student","george"], ["teacher","matz"]]
16 # c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
23 hash[key] = val unless hash.key?(key)
33 if result.size == self.size
43 # ary.uniq { |item| ... } -> new_ary
45 # Returns a new array by removing duplicate values in +self+.
47 # a = [ "a", "a", "b", "b", "c" ]
48 # a.uniq #=> ["a", "b", "c"]
50 # b = [["student","sam"], ["student","george"], ["teacher","matz"]]
51 # b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
61 # ary - other_ary -> new_ary
63 # Array Difference---Returns a new array that is a copy of
64 # the original array, removing any items that also appear in
65 # <i>other_ary</i>. (If you need set-like behavior, see the
68 # [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
71 raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array
78 hash[elem[idx]] = true
85 array << v unless hash[v]
93 # ary.difference(other_ary1, other_ary2, ...) -> new_ary
95 # Returns a new array that is a copy of the original array, removing all
96 # occurrences of any item that also appear in +other_ary+. The order is
97 # preserved from the original array.
109 # ary | other_ary -> new_ary
111 # Set Union---Returns a new array by joining this array with
112 # <i>other_ary</i>, removing duplicates.
114 # [ "a", "b", "c" ] | [ "c", "d", "a" ]
115 # #=> [ "a", "b", "c", "d" ]
118 raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array
126 # ary.union(other_ary,...) -> new_ary
128 # Set Union---Returns a new array by joining this array with
129 # <i>other_ary</i>, removing duplicates.
131 # ["a", "b", "c"].union(["c", "d", "a"], ["a", "c", "e"])
132 # #=> ["a", "b", "c", "d", "e"]
145 # ary & other_ary -> new_ary
147 # Set Intersection---Returns a new array
148 # containing elements common to the two arrays, with no duplicates.
150 # [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ]
153 raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array
160 hash[elem[idx]] = true
178 # ary.intersection(other_ary,...) -> new_ary
180 # Set Intersection---Returns a new array containing elements common to
181 # this array and <i>other_ary</i>s, removing duplicates. The order is
182 # preserved from the original array.
184 # [1, 2, 3].intersection([3, 4, 1], [1, 3, 5]) #=> [1, 3]
186 def intersection(*args)
196 # ary.flatten -> new_ary
197 # ary.flatten(level) -> new_ary
199 # Returns a new array that is a one-dimensional flattening of this
200 # array (recursively). That is, for every element that is an array,
201 # extract its elements into the new array. If the optional
202 # <i>level</i> argument determines the level of recursion to flatten.
204 # s = [ 1, 2, 3 ] #=> [1, 2, 3]
205 # t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
206 # a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
207 # a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
208 # a = [ 1, 2, [3, [4, 5] ] ]
209 # a.flatten(1) #=> [1, 2, 3, [4, 5]]
211 def flatten(depth=nil)
219 # ary.flatten! -> ary or nil
220 # ary.flatten!(level) -> array or nil
222 # Flattens +self+ in place.
223 # Returns <code>nil</code> if no modifications were made (i.e.,
224 # <i>ary</i> contains no subarrays.) If the optional <i>level</i>
225 # argument determines the level of recursion to flatten.
227 # a = [ 1, 2, [3, [4, 5] ] ]
228 # a.flatten! #=> [1, 2, 3, 4, 5]
230 # a #=> [1, 2, 3, 4, 5]
231 # a = [ 1, 2, [3, [4, 5] ] ]
232 # a.flatten!(1) #=> [1, 2, 3, [4, 5]]
234 def flatten!(depth=nil)
241 if e.is_a?(Array) && (depth.nil? || depth > 0)
242 ar += e.flatten(depth.nil? ? nil : depth - 1)
258 # ary.compact -> new_ary
260 # Returns a copy of +self+ with all +nil+ elements removed.
262 # [ "a", nil, "b", nil, "c", nil ].compact
263 # #=> [ "a", "b", "c" ]
273 # ary.compact! -> ary or nil
275 # Removes +nil+ elements from the array.
276 # Returns +nil+ if no changes were made, otherwise returns
279 # [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
280 # [ "a", "b", "c" ].compact! #=> nil
283 result = self.select { |e| !e.nil? }
284 if result.size == self.size
292 def reverse_each(&block)
293 return to_enum :reverse_each unless block
305 # ary.fetch(index) -> obj
306 # ary.fetch(index, default) -> obj
307 # ary.fetch(index) { |index| block } -> obj
309 # Tries to return the element at position +index+, but throws an IndexError
310 # exception if the referenced +index+ lies outside of the array bounds. This
311 # error can be prevented by supplying a second argument, which will act as a
314 # Alternatively, if a block is given it will only be executed when an
315 # invalid +index+ is referenced.
317 # Negative values of +index+ count from the end of the array.
319 # a = [ 11, 22, 33, 44 ]
322 # a.fetch(4, 'cat') #=> "cat"
323 # a.fetch(100) { |i| puts "#{i} is out of bounds" }
324 # #=> "100 is out of bounds"
327 def fetch(n, ifnone=NONE, &block)
328 warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block
334 if idx < 0 || size <= idx
335 return block.call(n) if block
337 raise IndexError, "index #{n} outside of array bounds: #{-size}...#{size}"
346 # ary.fill(obj) -> ary
347 # ary.fill(obj, start [, length]) -> ary
348 # ary.fill(obj, range ) -> ary
349 # ary.fill { |index| block } -> ary
350 # ary.fill(start [, length] ) { |index| block } -> ary
351 # ary.fill(range) { |index| block } -> ary
353 # The first three forms set the selected elements of +self+ (which
354 # may be the entire array) to +obj+.
356 # A +start+ of +nil+ is equivalent to zero.
358 # A +length+ of +nil+ is equivalent to the length of the array.
360 # The last three forms fill the array with the value of the given block,
361 # which is passed the absolute index of each element to be filled.
363 # Negative values of +start+ count from the end of the array, where +-1+ is
366 # a = [ "a", "b", "c", "d" ]
367 # a.fill("x") #=> ["x", "x", "x", "x"]
368 # a.fill("w", -1) #=> ["x", "x", "x", "w"]
369 # a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
370 # a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
371 # a.fill { |i| i*i } #=> [0, 1, 4, 9]
372 # a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27]
373 # a.fill(1, 2) { |i| i+1 } #=> [0, 2, 3, 27]
374 # a.fill(0..1) { |i| i+1 } #=> [1, 2, 3, 27]
377 def fill(arg0=nil, arg1=nil, arg2=nil, &block)
378 if arg0.nil? && arg1.nil? && arg2.nil? && !block
379 raise ArgumentError, "wrong number of arguments (0 for 1..3)"
385 if arg0.nil? && arg1.nil? && arg2.nil?
386 # ary.fill { |index| block } -> ary
389 elsif !arg0.nil? && arg0.kind_of?(Range)
390 # ary.fill(range) { |index| block } -> ary
392 beg += self.size if beg < 0
394 len += self.size if len < 0
395 len += 1 unless arg0.exclude_end?
397 # ary.fill(start [, length] ) { |index| block } -> ary
399 beg += self.size if beg < 0
407 if !arg0.nil? && arg1.nil? && arg2.nil?
408 # ary.fill(obj) -> ary
411 elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range)
412 # ary.fill(obj, range ) -> ary
414 beg += self.size if beg < 0
416 len += self.size if len < 0
417 len += 1 unless arg1.exclude_end?
418 elsif !arg0.nil? && !arg1.nil?
419 # ary.fill(obj, start [, length]) -> ary
421 beg += self.size if beg < 0
433 self[i] = block.call(i)
447 # ary.rotate(count=1) -> new_ary
449 # Returns a new array by rotating +self+ so that the element at +count+ is
450 # the first element of the new array.
452 # If +count+ is negative then it rotates in the opposite direction, starting
453 # from the end of +self+ where +-1+ is the last element.
455 # a = [ "a", "b", "c", "d" ]
456 # a.rotate #=> ["b", "c", "d", "a"]
457 # a #=> ["a", "b", "c", "d"]
458 # a.rotate(2) #=> ["c", "d", "a", "b"]
459 # a.rotate(-3) #=> ["b", "c", "d", "a"]
466 idx = (count < 0) ? (len - (~count % len) - 1) : (count % len) # rotate count
470 idx = 0 if idx > len-1
478 # ary.rotate!(count=1) -> ary
480 # Rotates +self+ in place so that the element at +count+ comes first, and
483 # If +count+ is negative then it rotates in the opposite direction, starting
484 # from the end of the array where +-1+ is the last element.
486 # a = [ "a", "b", "c", "d" ]
487 # a.rotate! #=> ["b", "c", "d", "a"]
488 # a #=> ["b", "c", "d", "a"]
489 # a.rotate!(2) #=> ["d", "a", "b", "c"]
490 # a.rotate!(-3) #=> ["a", "b", "c", "d"]
493 self.replace(self.rotate(count))
498 # ary.delete_if { |item| block } -> ary
499 # ary.delete_if -> Enumerator
501 # Deletes every element of +self+ for which block evaluates to +true+.
503 # The array is changed instantly every time the block is called, not after
504 # the iteration is over.
506 # See also Array#reject!
508 # If no block is given, an Enumerator is returned instead.
510 # scores = [ 97, 42, 75 ]
511 # scores.delete_if {|score| score < 80 } #=> [97]
513 def delete_if(&block)
514 return to_enum :delete_if unless block
517 while idx < self.size do
518 if block.call(self[idx])
529 # ary.reject! { |item| block } -> ary or nil
530 # ary.reject! -> Enumerator
532 # Equivalent to Array#delete_if, deleting elements from +self+ for which the
533 # block evaluates to +true+, but returns +nil+ if no changes were made.
535 # The array is changed instantly every time the block is called, not after
536 # the iteration is over.
538 # See also Enumerable#reject and Array#delete_if.
540 # If no block is given, an Enumerator is returned instead.
543 return to_enum :reject! unless block
547 while idx < self.size do
548 if block.call(self[idx])
563 # ary.insert(index, obj...) -> ary
565 # Inserts the given values before the element with the given +index+.
567 # Negative indices count backwards from the end of the array, where +-1+ is
571 # a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
572 # a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
574 def insert(idx, *args)
575 idx += self.size + 1 if idx < 0
582 # ary.bsearch {|x| block } -> elem
584 # By using binary search, finds a value from this array which meets
585 # the given condition in O(log n) where n is the size of the array.
587 # You can use this method in two use cases: a find-minimum mode and
588 # a find-any mode. In either case, the elements of the array must be
589 # monotone (or sorted) with respect to the block.
591 # In find-minimum mode (this is a good choice for typical use case),
592 # the block must return true or false, and there must be an index i
593 # (0 <= i <= ary.size) so that:
595 # - the block returns false for any element whose index is less than
597 # - the block returns true for any element whose index is greater
598 # than or equal to i.
600 # This method returns the i-th element. If i is equal to ary.size,
603 # ary = [0, 4, 7, 10, 12]
604 # ary.bsearch {|x| x >= 4 } #=> 4
605 # ary.bsearch {|x| x >= 6 } #=> 7
606 # ary.bsearch {|x| x >= -1 } #=> 0
607 # ary.bsearch {|x| x >= 100 } #=> nil
609 # In find-any mode (this behaves like libc's bsearch(3)), the block
610 # must return a number, and there must be two indices i and j
611 # (0 <= i <= j <= ary.size) so that:
613 # - the block returns a positive number for ary[k] if 0 <= k < i,
614 # - the block returns zero for ary[k] if i <= k < j, and
615 # - the block returns a negative number for ary[k] if
618 # Under this condition, this method returns any element whose index
619 # is within i...j. If i is equal to j (i.e., there is no element
620 # that satisfies the block), this method returns nil.
622 # ary = [0, 4, 7, 10, 12]
623 # # try to find v such that 4 <= v < 8
624 # ary.bsearch {|x| 1 - (x / 4).truncate } #=> 4 or 7
625 # # try to find v such that 8 <= v < 10
626 # ary.bsearch {|x| 4 - (x / 2).truncate } #=> nil
628 # You must not mix the two modes at a time; the block must always
629 # return either true/false, or always return a number. It is
630 # undefined which value is actually picked up at each iteration.
633 return to_enum :bsearch unless block
635 if idx = bsearch_index(&block)
644 # ary.bsearch_index {|x| block } -> int or nil
646 # By using binary search, finds an index of a value from this array which
647 # meets the given condition in O(log n) where n is the size of the array.
649 # It supports two modes, depending on the nature of the block and they are
650 # exactly the same as in the case of #bsearch method with the only difference
651 # being that this method returns the index of the element instead of the
652 # element itself. For more details consult the documentation for #bsearch.
654 def bsearch_index(&block)
655 return to_enum :bsearch_index unless block
662 mid = ((low+high)/2).truncate
663 res = block.call self[mid]
666 when 0 # find-any mode: Found!
668 when Numeric # find-any mode: Continue...
669 in_lower_half = res < 0
670 when true # find-min mode
673 when false, nil # find-min mode
674 in_lower_half = false
676 raise TypeError, 'invalid block result (must be numeric, true, false or nil)'
686 satisfied ? low : nil
691 # ary.keep_if { |item| block } -> ary
692 # ary.keep_if -> Enumerator
694 # Deletes every element of +self+ for which the given block evaluates to
697 # See also Array#select!
699 # If no block is given, an Enumerator is returned instead.
701 # a = [1, 2, 3, 4, 5]
702 # a.keep_if { |val| val > 3 } #=> [4, 5]
705 return to_enum :keep_if unless block
709 while idx < self.size do
710 if block.call(self[idx])
721 # ary.select! {|item| block } -> ary or nil
722 # ary.select! -> Enumerator
724 # Invokes the given block passing in successive elements from +self+,
725 # deleting elements for which the block returns a +false+ value.
727 # If changes were made, it will return +self+, otherwise it returns +nil+.
729 # See also Array#keep_if
731 # If no block is given, an Enumerator is returned instead.
734 return to_enum :select! unless block
741 result << elem if block.call(elem)
744 return nil if len == result.size
750 # ary.index(val) -> int or nil
751 # ary.index {|item| block } -> int or nil
753 # Returns the _index_ of the first object in +ary+ such that the object is
754 # <code>==</code> to +obj+.
756 # If a block is given instead of an argument, returns the _index_ of the
757 # first object for which the block returns +true+. Returns +nil+ if no
761 def index(val=NONE, &block)
762 return to_enum(:find_index, val) if !block && val == NONE
768 return idx if block.call self[idx]
772 return self.__ary_index(val)
779 # ary.dig(idx, ...) -> object
781 # Extracts the nested value specified by the sequence of <i>idx</i>
782 # objects by calling +dig+ at each step, returning +nil+ if any
783 # intermediate step is +nil+.
796 # ary.permutation { |p| block } -> ary
797 # ary.permutation -> Enumerator
798 # ary.permutation(n) { |p| block } -> ary
799 # ary.permutation(n) -> Enumerator
801 # When invoked with a block, yield all permutations of length +n+ of the
802 # elements of the array, then return the array itself.
804 # If +n+ is not specified, yield all permutations of all elements.
806 # The implementation makes no guarantees about the order in which the
807 # permutations are yielded.
809 # If no block is given, an Enumerator is returned instead.
814 # a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
815 # a.permutation(1).to_a #=> [[1],[2],[3]]
816 # a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
817 # a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
818 # a.permutation(0).to_a #=> [[]] # one permutation of length 0
819 # a.permutation(4).to_a #=> [] # no permutations of length 4
820 def permutation(n=self.size, &block)
821 return to_enum(:permutation, n) unless block
825 elsif 0 < n && n <= size
830 ary = self[0...i] + self[i+1..-1]
831 ary.permutation(n-1) do |c|
845 # ary.combination(n) { |c| block } -> ary
846 # ary.combination(n) -> Enumerator
848 # When invoked with a block, yields all combinations of length +n+ of elements
849 # from the array and then returns the array itself.
851 # The implementation makes no guarantees about the order in which the
852 # combinations are yielded.
854 # If no block is given, an Enumerator is returned instead.
859 # a.combination(1).to_a #=> [[1],[2],[3],[4]]
860 # a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
861 # a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
862 # a.combination(4).to_a #=> [[1,2,3,4]]
863 # a.combination(0).to_a #=> [[]] # one combination of length 0
864 # a.combination(5).to_a #=> [] # no combinations of length 5
866 def combination(n, &block)
867 return to_enum(:combination, n) unless block
881 self[i+1..-1].combination(n-1) do |c|
892 # ary.transpose -> new_ary
894 # Assumes that self is an array of arrays and transposes the rows and columns.
896 # If the length of the subarrays don't match, an IndexError is raised.
900 # a = [[1,2], [3,4], [5,6]]
901 # a.transpose #=> [[1, 3, 5], [2, 4, 6]]
908 raise TypeError unless row.is_a?(Array)
909 column_count ||= row.size
910 raise IndexError, 'element size differs' unless column_count == row.size
913 Array.new(column_count) do |column_index|
914 self.map { |row| row[column_index] }
921 # ary.to_h{|item| ... } -> Hash
923 # Returns the result of interpreting <i>aray</i> as an array of
924 # <tt>[key, value]</tt> pairs. If a block is given, it should
925 # return <tt>[key, value]</tt> pairs to construct a hash.
927 # [[:foo, :bar], [1, 2]].to_h
928 # # => {:foo => :bar, 1 => 2}
929 # [1, 2].to_h{|x| [x, x*2]}
930 # # => {1 => 2, 2 => 4}
935 v = blk.call(v) if blk
936 raise TypeError, "wrong element type #{v.class}" unless Array === v
937 raise ArgumentError, "wrong array length (expected 2, was #{v.length})" unless v.length == 2
944 alias prepend unshift
945 alias filter! select!