Class: Array

Inherits:
Object show all
Includes:
Enumerable
Defined in:
ext/enterprise_script_service/mruby/mrblib/array.rb,
ext/enterprise_script_service/mruby/test/assert.rb,
ext/enterprise_script_service/mruby/mrblib/array.rb,
ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb

Overview

Array is enumerable

Direct Known Subclasses

SubArray

Constant Summary

Constants included from Enumerable

Enumerable::NONE

Instance Method Summary collapse

Methods included from Enumerable

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

Constructor Details

#initialize(size = 0, obj = nil, &block) ⇒ Array

Private method for Array creation.

ISO 15.2.12.5.15

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 68

def initialize(size=0, obj=nil, &block)
  size = size.__to_int
  raise ArgumentError, "negative array size" if size < 0

  self.clear
  if size > 0
    self[size - 1] = nil # allocate

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

  self
end

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 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 152

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]
    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 'ext/enterprise_script_service/mruby/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

#<=>(other) ⇒ Object

Comparison—Returns an integer (-1, 0, or +1)

if this array is less than, equal to, or greater than <i>other_ary</i>.
Each object in each array is compared (using <=>). If any value isn't
equal, then that inequality is the return value. If all the
values found are equal, then the return is based on a
comparison of the array lengths.  Thus, two arrays are
"equal" according to <code>Array#<=></code> 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 array.

ISO 15.2.12.5.36 (x)



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 158

def <=>(other)
  other = self.__ary_cmp(other)
  return 0 if 0 == other
  return nil if nil == other

  len = self.size
  n = other.size
  len = n if len > n
  i = 0
  while i < len
    n = (self[i] <=> other[i])
    return n if n.nil? || n != 0
    i += 1
  end
  len = self.size - other.size
  if len == 0
    0
  elsif len > 0
    1
  else
    -1
  end
end

#==(other) ⇒ Object

Equality—Two arrays are equal if they contain the same number

of elements and if each element is equal to (according to
Object.==) the corresponding element in the other array.

ISO 15.2.12.5.33 (x)



115
116
117
118
119
120
121
122
123
124
125
126
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 115

def ==(other)
  other = self.__ary_eq(other)
  return false if other == false
  return true  if other == true
  len = self.size
  i = 0
  while i < len
    return false if self[i] != other[i]
    i += 1
  end
  return true
end

#_assertion_joinObject



24
25
26
# File 'ext/enterprise_script_service/mruby/test/assert.rb', line 24

def _assertion_join
  join("-")
end

#_inspect(recur_list) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 86

def _inspect(recur_list)
  size = self.size
  return "[]" if size == 0
  return "[...]" if recur_list[self.object_id]
  recur_list[self.object_id] = true
  ary=[]
  i=0
  while i<size
    ary<<self[i]._inspect(recur_list)
    i+=1
  end
  "["+ary.join(", ")+"]"
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[k] if 0 <= k < i,
- the block returns zero for ary[k] if i <= k < j, and
- the block returns a negative number for ary[k] 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.


632
633
634
635
636
637
638
639
640
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 632

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.


654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 654

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!

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



46
47
48
49
50
51
52
53
54
55
56
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 46

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


866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 866

def combination(n, &block)
  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

#compactObject

call-seq:

ary.compact     -> new_ary

Returns a copy of self with all nil elements removed.

[ "a", nil, "b", nil, "c", nil ].compact
                  #=> [ "a", "b", "c" ]


265
266
267
268
269
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 265

def compact
  result = self.dup
  result.compact!
  result
end

#compact!Object

call-seq:

ary.compact!    -> ary  or  nil

Removes nil elements from the array. Returns nil if no changes were made, otherwise returns ary.

[ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
[ "a", "b", "c" ].compact!           #=> nil


282
283
284
285
286
287
288
289
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 282

def compact!
  result = self.select { |e| !e.nil? }
  if result.size == self.size
    nil
  else
    self.replace(result)
  end
end

#delete(key, &block) ⇒ Object

Delete element with index key



184
185
186
187
188
189
190
191
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 184

def delete(key, &block)
  while i = self.index(key)
    self.delete_at(i)
    ret = key
  end
  return block.call if ret.nil? && block
  ret
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]


513
514
515
516
517
518
519
520
521
522
523
524
525
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 513

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

  idx = 0
  while idx < self.size do
    if block.call(self[idx])
      self.delete_at(idx)
    else
      idx += 1
    end
  end
  self
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 'ext/enterprise_script_service/mruby/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.



785
786
787
788
789
790
791
792
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 785

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

#each_index(&block) ⇒ Object

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

ISO 15.2.12.5.11



29
30
31
32
33
34
35
36
37
38
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 29

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

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

#eql?(other) ⇒ Boolean

Returns true if self and other are the same object,

or are both arrays with the same content.

ISO 15.2.12.5.34 (x)

Returns:

  • (Boolean)


133
134
135
136
137
138
139
140
141
142
143
144
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 133

def eql?(other)
  other = self.__ary_eq(other)
  return false if other == false
  return true  if other == true
  len = self.size
  i = 0
  while i < len
    return false unless self[i].eql?(other[i])
    i += 1
  end
  return true
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"


327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 327

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

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


377
378
379
380
381
382
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
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 377

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

  beg = len = 0
  ary = []
  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
      beg += self.size if beg < 0
      if arg1.nil?
        len = self.size
      else
        len = arg0 + arg1
      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
      beg += self.size if beg < 0
      if arg2.nil?
        len = self.size
      else
        len = beg + arg2
      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]]


211
212
213
214
215
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 211

def flatten(depth=nil)
  res = dup
  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]]


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 234

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

#index(val = NONE, &block) ⇒ Object

call-seq:

   ary.index(val)            -> int or nil
   ary.index {|item| block } ->  int or nil

Returns the _index_ of the first object in +ary+ such that the object is
<code>==</code> to +obj+.

If a block is given instead of an argument, returns the _index_ of the
first object for which the block returns +true+.  Returns +nil+ if no
match is found.

ISO 15.2.12.5.14



761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 761

def index(val=NONE, &block)
  return to_enum(:find_index, val) if !block && val == NONE

  if block
    idx = 0
    len = size
    while idx < len
      return idx if block.call self[idx]
      idx += 1
    end
  else
    return self.__ary_index(val)
  end
  nil
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"]


574
575
576
577
578
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 574

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

#inspectObject Also known as: to_s

Return the contents of this array as a string.

ISO 15.2.12.5.31 (x)



103
104
105
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 103

def inspect
  self._inspect({})
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 'ext/enterprise_script_service/mruby/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]


704
705
706
707
708
709
710
711
712
713
714
715
716
717
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 704

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

  idx = 0
  len = self.size
  while idx < self.size do
    if block.call(self[idx])
      idx += 1
    else
      self.delete_at(idx)
    end
  end
  self
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


820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 820

def permutation(n=self.size, &block)
  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

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


542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 542

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

  len = self.size
  idx = 0
  while idx < self.size do
    if block.call(self[idx])
      self.delete_at(idx)
    else
      idx += 1
    end
  end
  if self.size == len
    nil
  else
    self
  end
end

#reverse_each(&block) ⇒ Object

for efficiency



292
293
294
295
296
297
298
299
300
301
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 292

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

#rotate(count = 1) ⇒ Object

call-seq:

   ary.rotate(count=1)    -> new_ary

Returns a new array by rotating +self+ so that the element at +count+ is
the first element of the new array.

If +count+ is negative then it rotates in the opposite direction, starting
from the end of +self+ where +-1+ is the last element.

   a = [ "a", "b", "c", "d" ]
   a.rotate         #=> ["b", "c", "d", "a"]
   a                #=> ["a", "b", "c", "d"]
   a.rotate(2)      #=> ["c", "d", "a", "b"]
   a.rotate(-3)     #=> ["b", "c", "d", "a"]


461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 461

def rotate(count=1)
  ary = []
  len = self.length

  if len > 0
    idx = (count < 0) ? (len - (~count % len) - 1) : (count % len) # rotate count
    len.times do
      ary << self[idx]
      idx += 1
      idx = 0 if idx > len-1
    end
  end
  ary
end

#rotate!(count = 1) ⇒ Object

call-seq:

   ary.rotate!(count=1)   -> ary

Rotates +self+ in place so that the element at +count+ comes first, and
returns +self+.

If +count+ is negative then it rotates in the opposite direction, starting
from the end of the array where +-1+ is the last element.

   a = [ "a", "b", "c", "d" ]
   a.rotate!        #=> ["b", "c", "d", "a"]
   a                #=> ["b", "c", "d", "a"]
   a.rotate!(2)     #=> ["d", "a", "b", "c"]
   a.rotate!(-3)    #=> ["a", "b", "c", "d"]


492
493
494
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 492

def rotate!(count=1)
  self.replace(self.rotate(count))
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.


733
734
735
736
737
738
739
740
741
742
743
744
745
746
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 733

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



268
269
270
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 268

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

#sort!(&block) ⇒ Object

Sort all elements and replace self with these elements.



203
204
205
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 203

def sort!(&block)
  stack = [ [ 0, self.size - 1 ] ]
  until stack.empty?
    left, mid, right = stack.pop
    if right == nil
      right = mid
      # sort self[left..right]
      if left < right
        if left + 1 == right
          lval = self[left]
          rval = self[right]
          cmp = if block then block.call(lval,rval) else lval <=> rval end
          if cmp.nil?
            raise ArgumentError, "comparison of #{lval.inspect} and #{rval.inspect} failed"
          end
          if cmp > 0
            self[left]  = rval
            self[right] = lval
          end
        else
          mid = ((left + right + 1) / 2).floor
          stack.push [ left, mid, right ]
          stack.push [ mid, right ]
          stack.push [ left, (mid - 1) ] if left < mid - 1
        end
      end
    else
      lary = self[left, mid - left]
      lsize = lary.size

      # The entity sharing between lary and self may cause a large memory
      # copy operation in the merge loop below.  This harmless operation
      # cancels the sharing and provides a huge performance gain.
      lary[0] = lary[0]

      # merge
      lidx = 0
      ridx = mid
      (left..right).each { |i|
        if lidx >= lsize
          break
        elsif ridx > right
          self[i, lsize - lidx] = lary[lidx, lsize - lidx]
          break
        else
          lval = lary[lidx]
          rval = self[ridx]
          cmp = if block then block.call(lval,rval) else lval <=> rval end
          if cmp.nil?
            raise ArgumentError, "comparison of #{lval.inspect} and #{rval.inspect} failed"
          end
          if cmp <= 0
            self[i] = lval
            lidx += 1
          else
            self[i] = rval
            ridx += 1
          end
        end
      }
    end
  end
  self
end

#to_h(&blk) ⇒ Object

call-seq:

ary.to_h                ->   Hash
ary.to_h{|item| ... }   ->   Hash

Returns the result of interpreting aray 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}


932
933
934
935
936
937
938
939
940
941
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 932

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


903
904
905
906
907
908
909
910
911
912
913
914
915
916
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 903

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 'ext/enterprise_script_service/mruby/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 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 53

def uniq(&block)
  ary = self.dup
  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 'ext/enterprise_script_service/mruby/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 'ext/enterprise_script_service/mruby/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