Class: Array

Inherits:
Object show all
Includes:
Enumerable
Defined in:
ext/enterprise_script_service/mruby/mrblib/array.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, #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, to_h, #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:



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 136

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)



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

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)



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

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

#_inspectObject



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

def _inspect
  size = self.size
  return "[]" if size == 0
  ary=[]
  i=0
  while i<size
    ary<<self[i].inspect
    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.


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

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.


620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 620

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


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

def combination(n, &block)
  size = self.size
  return to_enum(:combination, n) unless block
  return if n > size
  if n == 0
     yield []
  elsif n == 1
    i = 0
    while i<size
      yield [self[i]]
      i += 1
    end
  else
    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
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" ]


231
232
233
234
235
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 231

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


248
249
250
251
252
253
254
255
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 248

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



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

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]


479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 479

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

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



782
783
784
785
786
787
788
789
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 782

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

#each(&block) ⇒ Object

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

ISO 15.2.12.5.10



13
14
15
16
17
18
19
20
21
22
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 13

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

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)


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

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"


293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 293

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]


343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
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
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 343

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


177
178
179
180
181
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 177

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


200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 200

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



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

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


540
541
542
543
544
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 540

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)



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

def inspect
  begin
    self._inspect
  rescue SystemStackError
    "[...]"
  end
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]


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

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


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

def permutation(n=self.size, &block)
  size = self.size
  return to_enum(:permutation, n) unless block
  return if n > size
  if n == 0
     yield []
  else
    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
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.


508
509
510
511
512
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 508

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



258
259
260
261
262
263
264
265
266
267
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 258

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


427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 427

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


458
459
460
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 458

def rotate!(count=1)
  self.replace(self.rotate(count))
end

#select!(&block) ⇒ Object

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.


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

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



270
271
272
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 270

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

#sort!(&block) ⇒ Object

Sort all elements and replace self with these elements.



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
267
268
# File 'ext/enterprise_script_service/mruby/mrblib/array.rb', line 205

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}


929
930
931
932
933
934
935
936
937
938
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 929

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


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

def transpose
  return [] if empty?

  column_count = nil
  self.each do |row|
    raise TypeError unless row.is_a?(Array)
    column_count ||= row.count
    raise IndexError, 'element size differs' unless column_count == row.count
  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"]


118
119
120
121
122
123
124
125
# File 'ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 118

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:



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

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

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