Class: Array

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
mrblib/array.rb,
mrbgems/mruby-enum-ext/mrblib/enum.rb,
mrbgems/mruby-array-ext/mrblib/array.rb

Overview

Array

ISO 15.2.12

Constant Summary

Constants included from Enumerable

Enumerable::NONE

Instance Method Summary collapse

Methods included from Enumerable

#all?, #any?, #chain, #chunk, #chunk_while, #collect, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #filter_map, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #hash, #include?, #inject, #lazy, #max, #max_by, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reject, #sum, #take, #take_while, #tally, #zip

Instance Method Details

#&(elem) ⇒ Object

call-seq: ary & other_ary -> new_ary

Set Intersection---Returns a new array containing elements common to the two arrays, with no duplicates.

[ 1, 1, 3, 5 ] & [ 1, 2, 3 ]   #=> [ 1, 3 ]

Raises:



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 152

def &(elem)
  raise TypeError, "cannot convert #{elem.class} into Array" unless elem.class == Array

  hash = {}
  array = []
  idx = 0
  len = elem.size
  while idx < len
    hash[elem[idx]] = true
    idx += 1
  end
  idx = 0
  len = size
  while idx < len
    v = self[idx]
    if hash[v]
      array << v
      hash.delete v
    end
    idx += 1
  end
  array
end

#-(elem) ⇒ Object

call-seq: ary - other_ary -> new_ary

Array Difference---Returns a new array that is a copy of the original array, removing any items that also appear in other_ary. (If you need set-like behavior, see the library class Set.)

[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ]  #=>  [ 3, 3, 5 ]

Raises:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 70

def -(elem)
  raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array

  hash = {}
  array = []
  idx = 0
  len = elem.size
  while idx < len
    hash[elem[idx]] = true
    idx += 1
  end
  idx = 0
  len = size
  while idx < len
    v = self[idx]
    array << v unless hash[v]
    idx += 1
  end
  array
end

#__repeated_combination(n, permutation, &block) ⇒ Object



970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 970

def __repeated_combination(n, permutation, &block)
  n = n.__to_int
  case n
  when 0
    yield []
  when 1
    i = 0
    while i < self.size
      yield [self[i]]
      i += 1
    end
  else
    if n > 0
      v = [0] * n
      while true
        tmp = [nil] * n
        i = 0
        while i < n
          tmp[i] = self[v[i]]
          i += 1
        end

        yield tmp

        tmp = self.size
        i = n - 1
        while i >= 0
          v[i] += 1
          break if v[i] < tmp
          i -= 1
        end
        break unless v[0] < tmp
        i = 1
        while i < n
          unless v[i] < tmp
            if permutation
              v[i] = 0
            else
              v[i] = v[i - 1]
            end
          end
          i += 1
        end
      end
    end
  end

  self
end

#bsearch(&block) ⇒ Object

call-seq: ary.bsearch {|x| block } -> elem

By using binary search, finds a value from this array which meets the given condition in O(log n) where n is the size of the array.

You can use this method in two use cases: a find-minimum mode and a find-any mode. In either case, the elements of the array must be monotone (or sorted) with respect to the block.

In find-minimum mode (this is a good choice for typical use case), the block must return true or false, and there must be an index i (0 <= i <= ary.size) so that:

  • the block returns false for any element whose index is less than i, and
  • the block returns true for any element whose index is greater than or equal to i.

This method returns the i-th element. If i is equal to ary.size, it returns nil.

ary = [0, 4, 7, 10, 12]
ary.bsearch {|x| x >=   4 } #=> 4
ary.bsearch {|x| x >=   6 } #=> 7
ary.bsearch {|x| x >=  -1 } #=> 0
ary.bsearch {|x| x >= 100 } #=> nil

In find-any mode (this behaves like libc's bsearch(3)), the block must return a number, and there must be two indices i and j (0 <= i <= j <= ary.size) so that:

  • the block returns a positive number for ary if 0 <= k < i,
  • the block returns zero for ary if i <= k < j, and
  • the block returns a negative number for ary if j <= k < ary.size.

Under this condition, this method returns any element whose index is within i...j. If i is equal to j (i.e., there is no element that satisfies the block), this method returns nil.

ary = [0, 4, 7, 10, 12]
# try to find v such that 4 <= v < 8
ary.bsearch {|x| 1 - (x / 4).truncate } #=> 4 or 7
# try to find v such that 8 <= v < 10
ary.bsearch {|x| 4 - (x / 2).truncate } #=> nil

You must not mix the two modes at a time; the block must always return either true/false, or always return a number. It is undefined which value is actually picked up at each iteration.



586
587
588
589
590
591
592
593
594
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 586

def bsearch(&block)
  return to_enum :bsearch unless block

  if idx = bsearch_index(&block)
    self[idx]
  else
    nil
  end
end

#bsearch_index(&block) ⇒ Object

call-seq: ary.bsearch_index {|x| block } -> int or nil

By using binary search, finds an index of a value from this array which meets the given condition in O(log n) where n is the size of the array.

It supports two modes, depending on the nature of the block and they are exactly the same as in the case of #bsearch method with the only difference being that this method returns the index of the element instead of the element itself. For more details consult the documentation for #bsearch.



608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 608

def bsearch_index(&block)
  return to_enum :bsearch_index unless block

  low = 0
  high = size
  satisfied = false

  while low < high
    mid = ((low+high)/2).truncate
    res = block.call self[mid]

    case res
    when 0 # find-any mode: Found!
      return mid
    when Numeric # find-any mode: Continue...
      in_lower_half = res < 0
    when true # find-min mode
      in_lower_half = true
      satisfied = true
    when false, nil # find-min mode
      in_lower_half = false
    else
      raise TypeError, 'invalid block result (must be numeric, true, false or nil)'
    end

    if in_lower_half
      high = mid
    else
      low = mid + 1
    end
  end

  satisfied ? low : nil
end

#collect!(&block) ⇒ Object Also known as: map!

call-seq: array.collect! {|element| ... } -> self array.collect! -> new_enumerator

Calls the given block for each element of self and pass the respective element. Each element will be replaced by the resulting values.

ISO 15.2.12.5.7



56
57
58
59
60
61
62
63
64
65
66
# File 'mrblib/array.rb', line 56

def collect!(&block)
  return to_enum :collect! unless block

  idx = 0
  len = size
  while idx < len
    self[idx] = block.call(self[idx])
    idx += 1
  end
  self
end

#combination(n, &block) ⇒ Object

call-seq: ary.combination(n) { |c| block } -> ary ary.combination(n) -> Enumerator

When invoked with a block, yields all combinations of length n of elements from the array and then returns the array itself.

The implementation makes no guarantees about the order in which the combinations are yielded.

If no block is given, an Enumerator is returned instead.

Examples:

a = [1, 2, 3, 4]
a.combination(1).to_a  #=> [[1],[2],[3],[4]]
a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
a.combination(4).to_a  #=> [[1,2,3,4]]
a.combination(0).to_a  #=> [[]] # one combination of length 0
a.combination(5).to_a  #=> []   # no combinations of length 5


795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 795

def combination(n, &block)
  n = n.__to_int
  return to_enum(:combination, n) unless block
  size = self.size
  if n == 0
    yield []
  elsif n == 1
    i = 0
    while i<size
      yield [self[i]]
      i += 1
    end
  elsif n <= size
    i = 0
    while i<size
      result = [self[i]]
      self[i+1..-1].combination(n-1) do |c|
        yield result + c
      end
      i += 1
    end
  end
  self
end

#delete_if(&block) ⇒ Object

call-seq: ary.delete_if { |item| block } -> ary ary.delete_if -> Enumerator

Deletes every element of self for which block evaluates to true.

The array is changed instantly every time the block is called, not after the iteration is over.

See also Array#reject!

If no block is given, an Enumerator is returned instead.

scores = [ 97, 42, 75 ]
scores.delete_if {|score| score < 80 }   #=> [97]


467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 467

def delete_if(&block)
  return to_enum :delete_if unless block

  result = []
  idx = 0
  len = size
  while idx < len
    elem = self[idx]
    result << elem unless block.call(elem)
    idx += 1
  end

  self.replace(result)
end

#difference(*args) ⇒ Object

call-seq: ary.difference(other_ary1, other_ary2, ...) -> new_ary

Returns a new array that is a copy of the original array, removing all occurrences of any item that also appear in other_ary. The order is preserved from the original array.



99
100
101
102
103
104
105
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 99

def difference(*args)
  ary = self
  args.each do |x|
    ary = ary - x
  end
  ary
end

#dig(idx, *args) ⇒ Object

call-seq: ary.dig(idx, ...) -> object

Extracts the nested value specified by the sequence of idx objects by calling dig at each step, returning nil if any intermediate step is nil.



712
713
714
715
716
717
718
719
720
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 712

def dig(idx,*args)
  idx = idx.__to_int
  n = self[idx]
  if args.size > 0
    n&.dig(*args)
  else
    n
  end
end

#each(&block) ⇒ Object

call-seq: array.each {|element| ... } -> self array.each -> Enumerator

Calls the given block for each element of self and pass the respective element.

ISO 15.2.12.5.10



15
16
17
18
19
20
21
22
23
24
# File 'mrblib/array.rb', line 15

def each(&block)
  return to_enum :each unless block

  idx = 0
  while idx < length
    block.call(self[idx])
    idx += 1
  end
  self
end

#each_index(&block) ⇒ Object

call-seq: array.each_index {|index| ... } -> self array.each_index -> Enumerator

Calls the given block for each element of self and pass the index of the respective element.

ISO 15.2.12.5.11



35
36
37
38
39
40
41
42
43
44
# File 'mrblib/array.rb', line 35

def each_index(&block)
  return to_enum :each_index unless block

  idx = 0
  while idx < length
    block.call(idx)
    idx += 1
  end
  self
end

#fetch(n, ifnone = NONE, &block) ⇒ Object

call-seq: ary.fetch(index) -> obj ary.fetch(index, default) -> obj ary.fetch(index) { |index| block } -> obj

Tries to return the element at position index, but throws an IndexError exception if the referenced index lies outside of the array bounds. This error can be prevented by supplying a second argument, which will act as a default value.

Alternatively, if a block is given it will only be executed when an invalid index is referenced.

Negative values of index count from the end of the array.

a = [ 11, 22, 33, 44 ]
a.fetch(1)               #=> 22
a.fetch(-1)              #=> 44
a.fetch(4, 'cat')        #=> "cat"
a.fetch(100) { |i| puts "#{i} is out of bounds" }
                         #=> "100 is out of bounds"


333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 333

def fetch(n, ifnone=NONE, &block)
  #warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block

  idx = n.__to_int
  if idx < 0
    idx += size
  end
  if idx < 0 || size <= idx
    return block.call(n) if block
    if NONE.equal?(ifnone)
      raise IndexError, "index #{n} outside of array bounds: #{-size}...#{size}"
    end
    return ifnone
  end
  self[idx]
end

#fetch_values(*idx, &block) ⇒ Object

call-seq: ary.fetch_values(idx, ...) -> array ary.fetch_values(idx, ...) { |i| block } -> array

Returns an array containing the values associated with the given indexes. but also raises IndexError when one of indexes can't be found. Also see Array#values_at and Array#fetch.

a = ["cat", "dog", "cow"]

a.fetch_values(2, 0)                #=> ["cow", "cat"]
a.fetch_values(2, 5)                # raises KeyError
a.fetch_values(2, 5) {|i| "BIRD" }  #=> ["cow", "BIRD"]


892
893
894
895
896
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 892

def fetch_values(*idx, &block)
  idx.map do |i|
    self.fetch(i, &block)
  end
end

#fill(arg0 = nil, arg1 = nil, arg2 = nil, &block) ⇒ Object

call-seq: ary.fill(obj) -> ary ary.fill(obj, start [, length]) -> ary ary.fill(obj, range ) -> ary ary.fill { |index| block } -> ary ary.fill(start [, length] ) { |index| block } -> ary ary.fill(range) { |index| block } -> ary

The first three forms set the selected elements of self (which may be the entire array) to obj.

A start of nil is equivalent to zero.

A length of nil is equivalent to the length of the array.

The last three forms fill the array with the value of the given block, which is passed the absolute index of each element to be filled.

Negative values of start count from the end of the array, where -1 is the last element.

a = [ "a", "b", "c", "d" ]
a.fill("x")              #=> ["x", "x", "x", "x"]
a.fill("w", -1)          #=> ["x", "x", "x", "w"]
a.fill("z", 2, 2)        #=> ["x", "x", "z", "z"]
a.fill("y", 0..1)        #=> ["y", "y", "z", "z"]
a.fill { |i| i*i }       #=> [0, 1, 4, 9]
a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27]
a.fill(1, 2) { |i| i+1 } #=> [0, 2, 3, 27]
a.fill(0..1) { |i| i+1 } #=> [1, 2, 3, 27]


383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 383

def fill(arg0=nil, arg1=nil, arg2=nil, &block)
  if arg0.nil? && arg1.nil? && arg2.nil? && !block
    raise ArgumentError, "wrong number of arguments (given 0, expected 1..3)"
  end

  beg = len = 0
  if block
    if arg0.nil? && arg1.nil? && arg2.nil?
      # ary.fill { |index| block }                    -> ary
      beg = 0
      len = self.size
    elsif !arg0.nil? && arg0.kind_of?(Range)
      # ary.fill(range) { |index| block }             -> ary
      beg = arg0.begin
      beg += self.size if beg < 0
      len = arg0.end
      len += self.size if len < 0
      len += 1 unless arg0.exclude_end?
    elsif !arg0.nil?
      # ary.fill(start [, length] ) { |index| block } -> ary
      beg = arg0.__to_int
      beg += self.size if beg < 0
      if arg1.nil?
        len = self.size
      else
        len = beg + arg1.__to_int
      end
    end
  else
    if !arg0.nil? && arg1.nil? && arg2.nil?
      # ary.fill(obj)                                 -> ary
      beg = 0
      len = self.size
    elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range)
      # ary.fill(obj, range )                         -> ary
      beg = arg1.begin
      beg += self.size if beg < 0
      len = arg1.end
      len += self.size if len < 0
      len += 1 unless arg1.exclude_end?
    elsif !arg0.nil? && !arg1.nil?
      # ary.fill(obj, start [, length])               -> ary
      beg = arg1.__to_int
      beg += self.size if beg < 0
      if arg2.nil?
        len = self.size
      else
        len = beg + arg2.__to_int
      end
    end
  end

  i = beg
  if block
    while i < len
      self[i] = block.call(i)
      i += 1
    end
  else
    while i < len
      self[i] = arg0
      i += 1
    end
  end
  self
end

#flatten(depth = nil) ⇒ Object

call-seq: ary.flatten -> new_ary ary.flatten(level) -> new_ary

Returns a new array that is a one-dimensional flattening of this array (recursively). That is, for every element that is an array, extract its elements into the new array. If the optional level argument determines the level of recursion to flatten.

s = [ 1, 2, 3 ]           #=> [1, 2, 3]
t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]
a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a = [ 1, 2, [3, [4, 5] ] ]
a.flatten(1)              #=> [1, 2, 3, [4, 5]]


252
253
254
255
256
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 252

def flatten(depth=nil)
  res = Array.new(self)
  res.flatten! depth
  res
end

#flatten!(depth = nil) ⇒ Object

call-seq: ary.flatten! -> ary or nil ary.flatten!(level) -> array or nil

Flattens self in place. Returns nil if no modifications were made (i.e., ary contains no subarrays.) If the optional level argument determines the level of recursion to flatten.

a = [ 1, 2, [3, [4, 5] ] ]
a.flatten!   #=> [1, 2, 3, 4, 5]
a.flatten!   #=> nil
a            #=> [1, 2, 3, 4, 5]
a = [ 1, 2, [3, [4, 5] ] ]
a.flatten!(1) #=> [1, 2, 3, [4, 5]]


275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 275

def flatten!(depth=nil)
  modified = false
  ar = []
  idx = 0
  len = size
  while idx < len
    e = self[idx]
    if e.is_a?(Array) && (depth.nil? || depth > 0)
      ar += e.flatten(depth.nil? ? nil : depth - 1)
      modified = true
    else
      ar << e
    end
    idx += 1
  end
  if modified
    self.replace(ar)
  else
    nil
  end
end

#insert(idx, *args) ⇒ Object

call-seq: ary.insert(index, obj...) -> ary

Inserts the given values before the element with the given index.

Negative indices count backwards from the end of the array, where -1 is the last element.

a = %w{ a b c d }
a.insert(2, 99)         #=> ["a", "b", 99, "c", "d"]
a.insert(-2, 1, 2, 3)   #=> ["a", "b", 99, "c", 1, 2, 3, "d"]


527
528
529
530
531
532
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 527

def insert(idx, *args)
  idx = idx.__to_int
  idx += self.size + 1 if idx < 0
  self[idx, 0] = args
  self
end

#intersect?(ary) ⇒ Boolean

call-seq: ary.intersect?(other_ary) -> true or false

Returns true if the array and other_ary have at least one element in common, otherwise returns false.

a = [ 1, 2, 3 ]
b = [ 3, 4, 5 ]
c = [ 5, 6, 7 ]
a.intersect?(b)   #=> true
a.intersect?(c)   #=> false

Returns:

  • (Boolean)

Raises:



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 206

def intersect?(ary)
  raise TypeError, "cannot convert #{ary.class} into Array" unless ary.class == Array

  hash = {}
  if self.length > ary.length
    shorter = ary
    longer = self
  else
    shorter = self
    longer = ary
  end
  idx = 0
  len = shorter.size
  while idx < len
    hash[shorter[idx]] = true
    idx += 1
  end
  idx = 0
  len = size
  while idx < len
    v = longer[idx]
    if hash[v]
      return true
    end
    idx += 1
  end
  false
end

#intersection(*args) ⇒ Object

call-seq: ary.intersection(other_ary,...) -> new_ary

Set Intersection---Returns a new array containing elements common to this array and other_arys, removing duplicates. The order is preserved from the original array.

[1, 2, 3].intersection([3, 4, 1], [1, 3, 5])  #=> [1, 3]


186
187
188
189
190
191
192
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 186

def intersection(*args)
  ary = self
  args.each do |x|
    ary = ary & x
  end
  ary
end

#keep_if(&block) ⇒ Object

call-seq: ary.keep_if { |item| block } -> ary ary.keep_if -> Enumerator

Deletes every element of self for which the given block evaluates to false.

See also Array#select!

If no block is given, an Enumerator is returned instead.

a = [1, 2, 3, 4, 5]
a.keep_if { |val| val > 3 } #=> [4, 5]


658
659
660
661
662
663
664
665
666
667
668
669
670
671
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 658

def keep_if(&block)
  return to_enum :keep_if unless block

  result = []
  idx = 0
  len = size
  while idx < len
    elem = self[idx]
    result << elem if block.call(elem)
    idx += 1
  end

  self.replace(result)
end

#permutation(n = self.size, &block) ⇒ Object

call-seq: ary.permutation { |p| block } -> ary ary.permutation -> Enumerator ary.permutation(n) { |p| block } -> ary ary.permutation(n) -> Enumerator

When invoked with a block, yield all permutations of length n of the elements of the array, then return the array itself.

If n is not specified, yield all permutations of all elements.

The implementation makes no guarantees about the order in which the permutations are yielded.

If no block is given, an Enumerator is returned instead.

Examples:

a = [1, 2, 3] a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] a.permutation(1).to_a #=> [[1],[2],[3]] a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] a.permutation(0).to_a #=> [[]] # one permutation of length 0 a.permutation(4).to_a #=> [] # no permutations of length 4



748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 748

def permutation(n=self.size, &block)
  n = n.__to_int
  return to_enum(:permutation, n) unless block
  size = self.size
  if n == 0
    yield []
  elsif 0 < n && n <= size
    i = 0
    while i<size
      result = [self[i]]
      if n-1 > 0
        ary = self[0...i] + self[i+1..-1]
        ary.permutation(n-1) do |c|
          yield result + c
        end
      else
        yield result
      end
      i += 1
    end
  end
  self
end

#product(*arys, &block) ⇒ Object

call-seq: ary.product(*arys) -> array ary.product(*arys) { |item| ... } -> self



902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 902

def product(*arys, &block)
  size = arys.size
  i = size
  while i > 0
    i -= 1
    unless arys[i].kind_of?(Array)
      raise TypeError, "no implicit conversion into Array"
    end
  end

  i = size
  total = self.size
  total *= arys[i -= 1].size while i > 0

  if block
    result = self
    list = ->(*, e) { block.call e }
    class << list; alias []= call; end
  else
    result = [nil] * total
    list = result
  end

  i = 0
  while i < total
    group = [nil] * (size + 1)
    j = size
    n = i
    while j > 0
      j -= 1
      a = arys[j]
      b = a.size
      group[j + 1] = a[n % b]
      n /= b
    end
    group[0] = self[n]
    list[i] = group
    i += 1
  end

  result
end

#reject!(&block) ⇒ Object

call-seq: ary.reject! { |item| block } -> ary or nil ary.reject! -> Enumerator

Equivalent to Array#delete_if, deleting elements from self for which the block evaluates to true, but returns nil if no changes were made.

The array is changed instantly every time the block is called, not after the iteration is over.

See also Enumerable#reject and Array#delete_if.

If no block is given, an Enumerator is returned instead.



497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 497

def reject!(&block)
  return to_enum :reject! unless block

  result = []
  idx = 0
  len = size
  while idx < len
    elem = self[idx]
    result << elem unless block.call(elem)
    idx += 1
  end

  return nil if len == result.size

  self.replace(result)
end

#repeated_combination(n, &block) ⇒ Object

call-seq: ary.repeated_combination(n) { |combination| ... } -> self ary.repeated_combination(n) -> enumerator

A combination method that contains the same elements.

Raises:



951
952
953
954
955
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 951

def repeated_combination(n, &block)
  raise TypeError, "no implicit conversion into Integer" unless 0 <=> n
  return to_enum(:repeated_combination, n) unless block
  __repeated_combination(n, false, &block)
end

#repeated_permutation(n, &block) ⇒ Object

call-seq: ary.repeated_permutation(n) { |permutation| ... } -> self ary.repeated_permutation(n) -> enumerator

A permutation method that contains the same elements.

Raises:



963
964
965
966
967
968
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 963

def repeated_permutation(n, &block)
  n = n.__to_int
  raise TypeError, "no implicit conversion into Integer" unless 0 <=> n
  return to_enum(:repeated_permutation, n) unless block
  __repeated_combination(n, true, &block)
end

#reverse_each(&block) ⇒ Object

for efficiency



298
299
300
301
302
303
304
305
306
307
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 298

def reverse_each(&block)
  return to_enum :reverse_each unless block

  i = self.size - 1
  while i>=0
    block.call(self[i])
    i -= 1
  end
  self
end

#select!(&block) ⇒ Object Also known as: filter!

call-seq: ary.select! {|item| block } -> ary or nil ary.select! -> Enumerator

Invokes the given block passing in successive elements from self, deleting elements for which the block returns a false value.

If changes were made, it will return self, otherwise it returns nil.

See also Array#keep_if

If no block is given, an Enumerator is returned instead.



687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 687

def select!(&block)
  return to_enum :select! unless block

  result = []
  idx = 0
  len = size
  while idx < len
    elem = self[idx]
    result << elem if block.call(elem)
    idx += 1
  end

  return nil if len == result.size

  self.replace(result)
end

#sort(&block) ⇒ Object

call-seq: array.sort -> new_array array.sort {|a, b| ... } -> new_array

Returns a new Array whose elements are those from self, sorted.



84
85
86
# File 'mrblib/array.rb', line 84

def sort(&block)
  self.dup.sort!(&block)
end

#sort_by(&block) ⇒ Object



921
922
923
924
925
926
927
928
929
930
931
932
# File 'mrbgems/mruby-enum-ext/mrblib/enum.rb', line 921

def sort_by(&block)
  return to_enum :sort_by unless block

  ary = []
  self.each_with_index{|e, i|
    ary.push([block.call(e), i])
  }
  if ary.size > 1
    ary.sort!
  end
  ary.collect!{|e,i| self[i]}
end

#sort_by!(&block) ⇒ Object



934
935
936
# File 'mrbgems/mruby-enum-ext/mrblib/enum.rb', line 934

def sort_by!(&block)
  self.replace(self.sort_by(&block))
end

#to_aObject Also known as: entries

call-seq: array.to_a -> self

Returns self, no need to convert.



93
94
95
# File 'mrblib/array.rb', line 93

def to_a
  self
end

#to_h(&blk) ⇒ Object

call-seq: ary.to_h -> Hash ary.to_h{|item| ... } -> Hash

Returns the result of interpreting array as an array of [key, value] pairs. If a block is given, it should return [key, value] pairs to construct a hash.

[[:foo, :bar], [1, 2]].to_h
  # => {:foo => :bar, 1 => 2}
[1, 2].to_h{|x| [x, x*2]}
  # => {1 => 2, 2 => 4}


862
863
864
865
866
867
868
869
870
871
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 862

def to_h(&blk)
  h = {}
  self.each do |v|
    v = blk.call(v) if blk
    raise TypeError, "wrong element type #{v.class}" unless Array === v
    raise ArgumentError, "wrong array length (expected 2, was #{v.length})" unless v.length == 2
    h[v[0]] = v[1]
  end
  h
end

#transposeObject

call-seq: ary.transpose -> new_ary

Assumes that self is an array of arrays and transposes the rows and columns.

If the length of the subarrays don't match, an IndexError is raised.

Examples:

a = [[1,2], [3,4], [5,6]]
a.transpose   #=> [[1, 3, 5], [2, 4, 6]]


833
834
835
836
837
838
839
840
841
842
843
844
845
846
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 833

def transpose
  return [] if empty?

  column_count = nil
  self.each do |row|
    raise TypeError unless row.is_a?(Array)
    column_count ||= row.size
    raise IndexError, 'element size differs' unless column_count == row.size
  end

  Array.new(column_count) do |column_index|
    self.map { |row| row[column_index] }
  end
end

#union(*args) ⇒ Object

call-seq: ary.union(other_ary,...) -> new_ary

Set Union---Returns a new array by joining this array with other_ary, removing duplicates.

["a", "b", "c"].union(["c", "d", "a"], ["a", "c", "e"])
      #=> ["a", "b", "c", "d", "e"]


134
135
136
137
138
139
140
141
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 134

def union(*args)
  ary = self.dup
  args.each do |x|
    ary.concat(x)
    ary.uniq!
  end
  ary
end

#uniq(&block) ⇒ Object

call-seq: ary.uniq -> new_ary ary.uniq { |item| ... } -> new_ary

Returns a new array by removing duplicate values in self.

a = [ "a", "a", "b", "b", "c" ]
a.uniq   #=> ["a", "b", "c"]

b = [["student","sam"], ["student","george"], ["teacher","matz"]]
b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]


53
54
55
56
57
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 53

def uniq(&block)
  ary = self[0..-1]
  ary.uniq!(&block)
  ary
end

#uniq!(&block) ⇒ Object

call-seq: ary.uniq! -> ary or nil ary.uniq! { |item| ... } -> ary or nil

Removes duplicate elements from self. Returns nil if no changes are made (that is, no duplicates are found).

a = [ "a", "a", "b", "b", "c" ]
a.uniq!   #=> ["a", "b", "c"]
b = [ "a", "b", "c" ]
b.uniq!   #=> nil
c = [["student","sam"], ["student","george"], ["teacher","matz"]]
c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 18

def uniq!(&block)
  hash = {}
  if block
    self.each do |val|
      key = block.call(val)
      hash[key] = val unless hash.key?(key)
    end
    result = hash.values
  else
    hash = {}
    self.each do |val|
      hash[val] = val
    end
    result = hash.keys
  end
  if result.size == self.size
    nil
  else
    self.replace(result)
  end
end

#|(elem) ⇒ Object

call-seq: ary | other_ary -> new_ary

Set Union---Returns a new array by joining this array with other_ary, removing duplicates.

[ "a", "b", "c" ] | [ "c", "d", "a" ]
      #=> [ "a", "b", "c", "d" ]

Raises:



117
118
119
120
121
122
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 117

def |(elem)
  raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array

  ary = self + elem
  ary.uniq! or ary
end