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, #entries, #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

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



676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 676

def __repeated_combination(n, permutation, &block)
  n = n.__to_int
  case n
  when 0
    yield []
  when 1
    # Keep fast Ruby path for n=1
    i = 0
    while i < self.size
      yield [self[i]]
      i += 1
    end
  else
    if n > 0
      # Use C iterator for complex cases
      state = __combination_init(n, permutation)
      while (indices = __combination_next(state))
        # Convert indices to elements in Ruby
        tmp = [nil] * n
        i = 0
        while i < n
          tmp[i] = self[indices[i]]
          i += 1
        end
        yield tmp
      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.



290
291
292
293
294
295
296
297
298
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 290

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.



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 312

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


499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 499

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

#deconstructObject

call-seq:

array.deconstruct -> self

Returns self. Used for array pattern matching in case/in expressions.



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

def deconstruct
  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]


189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 189

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

#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.



416
417
418
419
420
421
422
423
424
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 416

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
    yield 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
    yield 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"


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 99

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

  if block
    # Block case: use shared index helper + Ruby block handling
    normalized_index = __normalize_index(n)
    if normalized_index
      self[normalized_index]
    else
      block.call(n)
    end
  else
    # Fast C implementation for non-block cases
    __fetch(n, ifnone, NONE)
  end
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"]


596
597
598
599
600
601
602
603
604
605
606
607
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 596

def fetch_values(*idx, &block)
  if block
    idx.map do |i|
      self.fetch(i, &block)
    end
  else
    # Fast path: use C implementation for non-block cases
    idx.map do |i|
      __fetch(i, NONE, NONE)
    end
  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]


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

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

  # Use shared C argument parser for all cases
  start, length = __fill_parse_arg(arg0, arg1, arg2, &block)

  if block
    # Block-based filling in Ruby
    i = start
    while i < start + length
      self[i] = block.call(i)
      i += 1
    end
  else
    # Use fast C implementation for value filling
    __fill_exec(start, length, arg0)
  end

  self
end

#find(ifnone = nil, &block) ⇒ Object

call-seq:

ary.find(ifnone = nil) { |elem| block } -> obj or nil
ary.find(ifnone = nil)                  -> Enumerator

Returns the first element for which the block returns a true value. If no element matches and ifnone is given, calls ifnone and returns its result. Otherwise returns nil.

This is an optimized version of Enumerable#find for arrays.

[1, 2, 3, 4].find { |x| x > 2 }        #=> 3
[1, 2, 3, 4].find { |x| x > 10 }       #=> nil
[1, 2, 3, 4].find(->{0}) { |x| x > 10 } #=> 0


723
724
725
726
727
728
729
730
731
732
733
734
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 723

def find(ifnone=nil, &block)
  return to_enum(:find, ifnone) unless block

  idx = 0
  len = self.size
  while idx < len
    elem = self[idx]
    return elem if block.call(elem)
    idx += 1
  end
  ifnone&.call
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]


362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 362

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



452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 452

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


613
614
615
616
617
618
619
620
621
622
623
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 613

def product(*arys, &block)
  gen = __product_generate(arys, &block)
  return gen unless block

  if gen
    while group = __product_next(arys, gen)
      yield group
    end
  end
  self
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.



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 219

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| ... } -> ary
ary.repeated_combination(n)                         -> Enumerator

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

This means that, unlike combination, elements can be chosen more than once.

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]
a.repeated_combination(2).to_a #=> [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]]

Raises:

  • (TypeError)


644
645
646
647
648
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 644

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| ... } -> ary
ary.repeated_permutation(n)                         -> Enumerator

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

This means that, unlike permutation, elements can be chosen more than once.

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]
a.repeated_permutation(2).to_a #=> [[1,1],[1,2],[2,1],[2,2]]

Raises:

  • (TypeError)


669
670
671
672
673
674
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 669

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



64
65
66
67
68
69
70
71
72
73
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 64

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

#rfind(ifnone = nil, &block) ⇒ Object

call-seq:

ary.rfind(ifnone = nil) { |elem| block } -> obj or nil
ary.rfind(ifnone = nil)                  -> Enumerator

Returns the last element for which the block returns a true value. Searches from the end of the array to the beginning. If no element matches and ifnone is given, calls ifnone and returns its result. Otherwise returns nil.

[1, 2, 3, 4, 3].rfind { |x| x == 3 }     #=> 3 (the last one)
[1, 2, 3, 4].rfind { |x| x > 2 }         #=> 4
[1, 2, 3, 4].rfind { |x| x > 10 }        #=> nil
[1, 2, 3, 4].rfind(->{0}) { |x| x > 10 } #=> 0


751
752
753
754
755
756
757
758
759
760
761
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 751

def rfind(ifnone=nil, &block)
  return to_enum(:rfind, ifnone) unless block

  idx = self.size - 1
  while idx >= 0
    elem = self[idx]
    return elem if block.call(elem)
    idx -= 1
  end
  ifnone&.call
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.



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 391

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



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

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



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

def sort_by!(&block)
  self.replace(self.sort_by(&block))
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}


566
567
568
569
570
571
572
573
574
575
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 566

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]]


537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 537

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

#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
58
59
60
61
# File 'mrbgems/mruby-array-ext/mrblib/array.rb', line 53

def uniq(&block)
  if block
    ary = self.dup
    ary.uniq!(&block)
    ary
  else
    __uniq
  end
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)
  if block
    hash = {}
    result = []
    self.each do |val|
      key = block.call(val)
      unless hash.key?(key)
        hash[key] = true
        result << val
      end
    end

    if result.size == self.size
      nil
    else
      self.replace(result)
    end
  else
    __uniq!
  end
end