Class: Array

Inherits:
Object show all
Includes:
Enumerable
Defined in:
gems/carbuncle-doc-ext/mrblib/array.rb,
mruby/src/array.c,
mruby/mrblib/array.rb,
mruby/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

__update_hash, #all?, #any?, #chain, #collect, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_slice, #each_with_index, #each_with_object, #filter_map, #find_all, #find_index, #flat_map, #grep, #group_by, #hash, #include?, #inject, #lazy, #max, #max_by, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reject, #sort_by, #sum, #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:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'mruby/mrblib/array.rb', line 82

def initialize(size=0, obj=nil, &block)
  if size.is_a?(Array) && obj==nil && block == nil
    self.replace(size)
    return self
  end
  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 'mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 152

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

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

#*Object

15.2.12.5.2



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'mruby/src/array.c', line 448

static mrb_value
mrb_ary_times(mrb_state *mrb, mrb_value self)
{
  struct RArray *a1 = mrb_ary_ptr(self);
  struct RArray *a2;
  mrb_value *ptr, sep, tmp;
  mrb_int times, len1;

  mrb_get_args(mrb, "o", &sep);
  tmp = mrb_check_string_type(mrb, sep);
  if (!mrb_nil_p(tmp)) {
    return mrb_ary_join(mrb, self, tmp);
  }

  mrb_get_args(mrb, "i", &times);
  if (times < 0) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
  }
  if (times == 0) return mrb_ary_new(mrb);
  if (ARY_MAX_SIZE / times < ARY_LEN(a1)) {
    ary_too_big(mrb);
  }
  len1 = ARY_LEN(a1);
  a2 = ary_new_capa(mrb, len1 * times);
  ARY_SET_LEN(a2, len1 * times);
  ptr = ARY_PTR(a2);
  while (times--) {
    array_copy(ptr, ARY_PTR(a1), len1);
    ptr += len1;
  }

  return mrb_obj_value(a2);
}

#+Object

15.2.12.5.1



364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'mruby/src/array.c', line 364

static mrb_value
mrb_ary_plus(mrb_state *mrb, mrb_value self)
{
  struct RArray *a1 = mrb_ary_ptr(self);
  struct RArray *a2;
  const mrb_value *ptr;
  mrb_int blen, len1;

  mrb_get_args(mrb, "a", &ptr, &blen);
  ary_check_too_big(mrb, ARY_LEN(a1), blen);
  len1 = ARY_LEN(a1);
  a2 = ary_new_capa(mrb, len1 + blen);
  array_copy(ARY_PTR(a2), ARY_PTR(a1), len1);
  array_copy(ARY_PTR(a2) + len1, ptr, blen);
  ARY_SET_LEN(a2, len1+blen);

  return mrb_obj_value(a2);
}

#-(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 '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

#<<Object

15.2.12.5.3



538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
# File 'mruby/src/array.c', line 538

static mrb_value
mrb_ary_push_m(mrb_state *mrb, mrb_value self)
{
  mrb_int argc;
  const mrb_value *argv;
  mrb_int len, len2;
  struct RArray *a;

  a = mrb_ary_ptr(self);
  ary_modify(mrb, a);
  argc = mrb_get_argc(mrb);
  len = ARY_LEN(a);
  len2 = len + argc;
  if (ARY_CAPA(a) < len2) {
    ary_expand_capa(mrb, a, len2);
  }
  argv = mrb_get_argv(mrb);
  array_copy(ARY_PTR(a)+len, argv, argc);
  ARY_SET_LEN(a, len2);
  while (argc--) {
    mrb_field_write_barrier_value(mrb, (struct RBasic*)a, *argv);
    argv++;
  }
  return self;
}

#<=>(other) ⇒ Object

call-seq:

 array <=> other_array -> -1, 0, or 1

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.


180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'mruby/mrblib/array.rb', line 180

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

#==(other) ⇒ Object

call-seq:

 array == other   -> true or false

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.


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

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

#[](index) ⇒ Object? #[](start, length) ⇒ Array? #[](range) ⇒ Array? #slice(index) ⇒ Object? #slice(start, length) ⇒ Array? #slice(range) ⇒ Array?

Element Reference — Returns the element at index, or returns a subarray starting at the start index and continuing for length elements, or returns a subarray specified by range of indices.

Negative indices count backward from the end of the array (-1 is the last element). For start and range cases the starting index is just before an element. Additionally, an empty array is returned when the starting index for an element range is at the end of the array.

Returns nil if the index (or starting index) are out of range.

a = [ “a”, “b”, “c”, “d”, “e” ] a => “b” a => [“b”, “c”] a => [“b”, “c”, “d”]

Overloads:



950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
# File 'mruby/src/array.c', line 950

static mrb_value
mrb_ary_aget(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int i;
  mrb_int len, alen;
  mrb_value index;

  if (mrb_get_argc(mrb) == 1) {
    index = mrb_get_arg1(mrb);
    switch (mrb_type(index)) {
      /* a[n..m] */
    case MRB_TT_RANGE:
      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
        return ary_subseq(mrb, a, i, len);
      }
      else {
        return mrb_nil_value();
      }
    case MRB_TT_INTEGER:
      return mrb_ary_ref(mrb, self, mrb_integer(index));
    default:
      return mrb_ary_ref(mrb, self, aget_index(mrb, index));
    }
  }

  mrb_get_args(mrb, "oi", &index, &len);
  i = aget_index(mrb, index);
  alen = ARY_LEN(a);
  if (i < 0) i += alen;
  if (i < 0 || alen < i) return mrb_nil_value();
  if (len < 0) return mrb_nil_value();
  if (alen == i) return mrb_ary_new(mrb);
  if (len > alen - i) len = alen - i;

  return ary_subseq(mrb, a, i, len);
}

#[]=(index) ⇒ Object #[]=(start, length) ⇒ Object? #[]=(range) ⇒ Object?

Element Assignment — Sets the element at index, or replaces a subarray from the start index for length elements, or replaces a subarray specified by the range of indices.

If indices are greater than the current capacity of the array, the array grows automatically. Elements are inserted into the array at start if length is zero.

Negative indices will count backward from the end of the array. For start and range cases the starting index is just before an element.

An IndexError is raised if a negative index points past the beginning of the array.

See also Array#push, and Array#unshift.

a = Array.new
a[4] = "4";                 #=> [nil, nil, nil, nil, "4"]
a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
a[1..2] = [ 1, 2 ]          #=> ["a", 1, 2, nil, "4"]
a[0, 2] = "?"               #=> ["?", 2, nil, "4"]
a[0..2] = "A"               #=> ["A", "4"]
a[-1]   = "Z"               #=> ["A", "Z"]
a[1..-1] = nil              #=> ["A", nil]
a[1..-1] = []               #=> ["A"]
a[0, 0] = [ 1, 2 ]          #=> [1, 2, "A"]
a[3, 0] = "B"               #=> [1, 2, "A", "B"]

Overloads:



1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
# File 'mruby/src/array.c', line 1023

static mrb_value
mrb_ary_aset(mrb_state *mrb, mrb_value self)
{
  mrb_value v1, v2, v3;
  mrb_int i, len;

  ary_modify(mrb, mrb_ary_ptr(self));
  if (mrb_get_argc(mrb) == 2) {
    const mrb_value *vs = mrb_get_argv(mrb);
    v1 = vs[0]; v2 = vs[1];

    /* a[n..m] = v */
    switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
    case MRB_RANGE_TYPE_MISMATCH:
      mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
      break;
    case MRB_RANGE_OK:
      mrb_ary_splice(mrb, self, i, len, v2);
      break;
    case MRB_RANGE_OUT:
      mrb_raisef(mrb, E_RANGE_ERROR, "%v out of range", v1);
      break;
    }
    return v2;
  }

  mrb_get_args(mrb, "ooo", &v1, &v2, &v3);
  /* a[n,m] = v */
  mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3);
  return v3;
}

#__ary_cmpObject



1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
# File 'mruby/src/array.c', line 1346

static mrb_value
mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
{
  mrb_value ary2 = mrb_get_arg1(mrb);

  mrb->c->ci->mid = 0;
  if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0);
  if (!mrb_array_p(ary2)) {
    return mrb_nil_value();
  }

  return ary2;
}

#__ary_eqObject

15.2.12.5.30



1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
# File 'mruby/src/array.c', line 1331

static mrb_value
mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
{
  mrb_value ary2 = mrb_get_arg1(mrb);

  mrb->c->ci->mid = 0;
  if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
  if (!mrb_array_p(ary2)) {
    return mrb_false_value();
  }
  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();

  return ary2;
}

#__ary_indexObject

kept for mruby-array-ext



1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
# File 'mruby/src/array.c', line 1130

static mrb_value
mrb_ary_index_m(mrb_state *mrb, mrb_value self)
{
  mrb_value obj = mrb_get_arg1(mrb);
  mrb_int i;

  for (i = 0; i < RARRAY_LEN(self); i++) {
    if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
      return mrb_int_value(mrb, i);
    }
  }
  return mrb_nil_value();
}

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



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

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

        yield tmp

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

  self
end

#__svalueObject

internal method to convert multi-value to single value



1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
# File 'mruby/src/array.c', line 1361

static mrb_value
mrb_ary_svalue(mrb_state *mrb, mrb_value ary)
{
  switch (RARRAY_LEN(ary)) {
  case 0:
    return mrb_nil_value();
  case 1:
    return RARRAY_PTR(ary)[0];
  default:
    return ary;
  }
}

#_inspect(recur_list) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'mruby/mrblib/array.rb', line 104

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

#assoc(obj) ⇒ Array?

Searches through an array whose elements are also arrays comparing obj with the first element of each contained array using obj.==. Returns the first contained array that matches (that is, the first associated array), or nil if no match is found. See also Array#rassoc.

s1 = [ "colors", "red", "blue", "green" ]
s2 = [ "letters", "a", "b", "c" ]
s3 = "foo"
a  = [ s1, s2, s3 ]
a.assoc("letters")  #=> [ "letters", "a", "b", "c" ]
a.assoc("foo")      #=> nil

Returns:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 29

static mrb_value
mrb_ary_assoc(mrb_state *mrb, mrb_value ary)
{
  mrb_int i;
  mrb_value v;
  mrb_value k = mrb_get_arg1(mrb);

  for (i = 0; i < RARRAY_LEN(ary); i++) {
    v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
    if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 &&
        mrb_equal(mrb, RARRAY_PTR(v)[0], k))
      return v;
  }
  return mrb_nil_value();
}

#at(index) ⇒ Object?

Returns the element at index. A negative index counts from the end of self. Returns nil if the index is out of range. See also Array#[].

a = [ "a", "b", "c", "d", "e" ]
a.at(0)     #=> "a"
a.at(-1)    #=> "e"

Returns:



89
90
91
92
93
94
95
96
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 89

static mrb_value
mrb_ary_at(mrb_state *mrb, mrb_value ary)
{
  mrb_int pos;
  mrb_get_args(mrb, "i", &pos);

  return mrb_ary_entry(ary, pos);
}

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


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

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

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

#bsearch_index(&block) ⇒ Object

call-seq:

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

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

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


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

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

  low = 0
  high = size
  satisfied = false

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

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

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

  satisfied ? low : nil
end

#clearObject

15.2.12.5.6



1218
1219
1220
1221
1222
# File 'mruby/src/array.c', line 1218

static mrb_value
mrb_ary_clear_m(mrb_state *mrb, mrb_value self)
{
  return mrb_ary_clear(mrb, self);
}

#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 'mruby/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


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

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

#compactArray

Returns a copy of self with all nil elements removed.

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

Returns:



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

static mrb_value
mrb_ary_compact(mrb_state *mrb, mrb_value self)
{
  mrb_value ary = mrb_ary_new(mrb);
  mrb_int len = RARRAY_LEN(self);
  mrb_value *p = RARRAY_PTR(self);

  for (mrb_int i = 0; i < len; i++) {
    if (!mrb_nil_p(p[i])) {
      mrb_ary_push(mrb, ary, p[i]);
    }
  }
  return ary;
}

#compact!Array?

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

Returns:



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 215

static mrb_value
mrb_ary_compact_bang(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int i, j = 0;
  mrb_int len = ARY_LEN(a);
  mrb_value *p = ARY_PTR(a);

  mrb_ary_modify(mrb, a);
  for (i = 0; i < len; i++) {
    if (!mrb_nil_p(p[i])) {
      if (i != j) p[j] = p[i];
      j++;
    }
  }
  if (i == j) return mrb_nil_value();
  if (j < len) ARY_SET_LEN(RARRAY(self), j);
  return self;
}

#concat(*other_arrays) ⇒ self

Adds to array all elements from each Array in other_arrays; returns self:

a = [0, 1]
a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]

Returns:

  • (self)


348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'mruby/src/array.c', line 348

static mrb_value
mrb_ary_concat_m(mrb_state *mrb, mrb_value self)
{
  mrb_value *args;
  mrb_int len;

  mrb_get_args(mrb, "*!", &args, &len);
  for (int i=0; i<len; i++) {
    mrb_ensure_array_type(mrb, args[i]);
  }
  for (int i=0; i<len; i++) {
    mrb_ary_concat(mrb, self, args[i]);
  }
  return self;
}

#delete(key, &block) ⇒ Object

call-seq:

array.delete(obj) -> deleted_object
array.delete(obj) {|nosuch| ... } -> deleted_object or block_return

Delete element with index key



214
215
216
217
218
219
220
221
# File 'mruby/mrblib/array.rb', line 214

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_atObject

15.2.12.5.9



1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
# File 'mruby/src/array.c', line 1055

mrb_value
mrb_ary_delete_at(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int   index;
  mrb_value val;
  mrb_value *ptr;
  mrb_int len, alen;

  mrb_get_args(mrb, "i", &index);
  alen = ARY_LEN(a);
  if (index < 0) index += alen;
  if (index < 0 || alen <= index) return mrb_nil_value();

  ary_modify(mrb, a);
  ptr = ARY_PTR(a);
  val = ptr[index];

  ptr += index;
  len = alen - index;
  while (--len) {
    *ptr = *(ptr+1);
    ptr++;
  }
  ARY_SET_LEN(a, alen-1);

  ary_shrink_capa(mrb, a);

  return val;
}

#delete_if(&block) ⇒ Object

call-seq:

   ary.delete_if { |item| block }  -> ary
   ary.delete_if                   -> Enumerator

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

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

See also Array#reject!

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

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


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

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



738
739
740
741
742
743
744
745
# File 'mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 738

def dig(idx,*args)
  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 'mruby/mrblib/array.rb', line 15

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

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

#each_index(&block) ⇒ Object

call-seq:

array.each_index {|index| ... } -> self
array.each_index -> Enumerator

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

ISO 15.2.12.5.11



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

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

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

#empty?Boolean

15.2.12.5.12

Returns:

  • (Boolean)


1224
1225
1226
1227
1228
1229
1230
# File 'mruby/src/array.c', line 1224

static mrb_value
mrb_ary_empty_p(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);

  return mrb_bool_value(ARY_LEN(a) == 0);
}

#eql?(other) ⇒ Boolean

call-seq:

 array.eql? other_array -> true or false

Returns <code>true</code> if +self+ and _other_ are the same object,
or are both arrays with the same content.

Returns:

  • (Boolean)


153
154
155
156
157
158
159
160
161
162
163
164
# File 'mruby/mrblib/array.rb', line 153

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"


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

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

  idx = n
  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]


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

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

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

#firstObject

15.2.12.5.13



1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'mruby/src/array.c', line 1086

static mrb_value
mrb_ary_first(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int size, alen;

  if (mrb_get_argc(mrb) == 0) {
    return (ARY_LEN(a) > 0)? ARY_PTR(a)[0]: mrb_nil_value();
  }
  mrb_get_args(mrb, "|i", &size);
  if (size < 0) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
  }

  alen = ARY_LEN(a);
  if (size > alen) size = alen;
  if (ARY_SHARED_P(a)) {
    return ary_subseq(mrb, a, 0, size);
  }
  return mrb_ary_new_from_values(mrb, size, ARY_PTR(a));
}

#flatten(depth = nil) ⇒ Object

call-seq:

ary.flatten -> new_ary
ary.flatten(level) -> new_ary

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

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


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

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

#flatten!(depth = nil) ⇒ Object

call-seq:

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

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

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


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

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

#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



1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
# File 'mruby/src/array.c', line 1130

static mrb_value
mrb_ary_index_m(mrb_state *mrb, mrb_value self)
{
  mrb_value obj = mrb_get_arg1(mrb);
  mrb_int i;

  for (i = 0; i < RARRAY_LEN(self); i++) {
    if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
      return mrb_int_value(mrb, i);
    }
  }
  return mrb_nil_value();
}

#initialize_copyObject

15.2.12.5.16



437
438
439
440
441
442
443
444
445
446
# File 'mruby/src/array.c', line 437

static mrb_value
mrb_ary_replace_m(mrb_state *mrb, mrb_value self)
{
  mrb_value other;

  mrb_get_args(mrb, "A", &other);
  mrb_ary_replace(mrb, self, other);

  return self;
}

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


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

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.



120
121
122
# File 'mruby/mrblib/array.rb', line 120

def inspect
  self._inspect({})
end

#intersect?(ary) ⇒ Boolean

call-seq:

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

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

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

Returns:

  • (Boolean)

Raises:



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

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

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

#intersection(*args) ⇒ Object

call-seq:

ary.intersection(other_ary,...)  -> new_ary

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

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


186
187
188
189
190
191
192
# File '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

#join(sep = "") ⇒ String

Returns a string created by converting each element of the array to a string, separated by sep.

[ "a", "b", "c" ].join        #=> "abc"
[ "a", "b", "c" ].join("-")   #=> "a-b-c"

Returns:



1322
1323
1324
1325
1326
1327
1328
1329
# File 'mruby/src/array.c', line 1322

static mrb_value
mrb_ary_join_m(mrb_state *mrb, mrb_value ary)
{
  mrb_value sep = mrb_nil_value();

  mrb_get_args(mrb, "|S!", &sep);
  return mrb_ary_join(mrb, ary, sep);
}

#keep_if(&block) ⇒ Object

call-seq:

   ary.keep_if { |item| block } -> ary
   ary.keep_if                  -> Enumerator

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

See also Array#select!

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

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


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

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

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

#lastObject

15.2.12.5.18



1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
# File 'mruby/src/array.c', line 1108

static mrb_value
mrb_ary_last(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int n, size, alen;

  n = mrb_get_args(mrb, "|i", &size);
  alen = ARY_LEN(a);
  if (n == 0) {
    return (alen > 0) ? ARY_PTR(a)[alen - 1]: mrb_nil_value();
  }

  if (size < 0) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
  }
  if (size > alen) size = alen;
  if (ARY_SHARED_P(a) || size > ARY_DEFAULT_LEN) {
    return ary_subseq(mrb, a, alen - size, size);
  }
  return mrb_ary_new_from_values(mrb, size, ARY_PTR(a) + alen - size);
}

#lengthObject

15.2.12.5.19



1186
1187
1188
1189
1190
1191
1192
# File 'mruby/src/array.c', line 1186

static mrb_value
mrb_ary_size(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);

  return mrb_int_value(mrb, ARY_LEN(a));
}

#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


773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
# File 'mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 773

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

#popObject

15.2.12.5.21



564
565
566
567
568
569
570
571
572
573
574
# File 'mruby/src/array.c', line 564

MRB_API mrb_value
mrb_ary_pop(mrb_state *mrb, mrb_value ary)
{
  struct RArray *a = mrb_ary_ptr(ary);
  mrb_int len = ARY_LEN(a);

  ary_modify_check(mrb, a);
  if (len == 0) return mrb_nil_value();
  ARY_SET_LEN(a, len-1);
  return ARY_PTR(a)[len-1];
}

#product(*arys, &block) ⇒ Object

call-seq:

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


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

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

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

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

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

  result
end

#pushObject Also known as: append

15.2.12.5.22



538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
# File 'mruby/src/array.c', line 538

static mrb_value
mrb_ary_push_m(mrb_state *mrb, mrb_value self)
{
  mrb_int argc;
  const mrb_value *argv;
  mrb_int len, len2;
  struct RArray *a;

  a = mrb_ary_ptr(self);
  ary_modify(mrb, a);
  argc = mrb_get_argc(mrb);
  len = ARY_LEN(a);
  len2 = len + argc;
  if (ARY_CAPA(a) < len2) {
    ary_expand_capa(mrb, a, len2);
  }
  argv = mrb_get_argv(mrb);
  array_copy(ARY_PTR(a)+len, argv, argc);
  ARY_SET_LEN(a, len2);
  while (argc--) {
    mrb_field_write_barrier_value(mrb, (struct RBasic*)a, *argv);
    argv++;
  }
  return self;
}

#rassoc(obj) ⇒ Array?

Searches through the array whose elements are also arrays. Compares obj with the second element of each contained array using ==. Returns the first contained array that matches. See also Array#assoc.

a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
a.rassoc("two")    #=> [2, "two"]
a.rassoc("four")   #=> nil

Returns:



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 59

static mrb_value
mrb_ary_rassoc(mrb_state *mrb, mrb_value ary)
{
  mrb_int i;
  mrb_value v;
  mrb_value value = mrb_get_arg1(mrb);

  for (i = 0; i < RARRAY_LEN(ary); i++) {
    v = RARRAY_PTR(ary)[i];
    if (mrb_array_p(v) &&
        RARRAY_LEN(v) > 1 &&
        mrb_equal(mrb, RARRAY_PTR(v)[1], value))
      return v;
  }
  return mrb_nil_value();
}

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


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

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

#repeated_combination(n, &block) ⇒ Object

call-seq:

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

A combination method that contains the same elements.

Raises:



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

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

#repeated_permutation(n, &block) ⇒ Object

call-seq:

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

A permutation method that contains the same elements.

Raises:



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

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

#replaceObject

15.2.12.5.23



437
438
439
440
441
442
443
444
445
446
# File 'mruby/src/array.c', line 437

static mrb_value
mrb_ary_replace_m(mrb_state *mrb, mrb_value self)
{
  mrb_value other;

  mrb_get_args(mrb, "A", &other);
  mrb_ary_replace(mrb, self, other);

  return self;
}

#reverseObject

15.2.12.5.24



504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'mruby/src/array.c', line 504

static mrb_value
mrb_ary_reverse(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, ARY_LEN(a));
  mrb_int len = ARY_LEN(a);

  if (len > 0) {
    mrb_value *p1, *p2, *e;

    p1 = ARY_PTR(a);
    e  = p1 + len;
    p2 = ARY_PTR(b) + len - 1;
    while (p1 < e) {
      *p2-- = *p1++;
    }
    ARY_SET_LEN(b, len);
  }
  return mrb_obj_value(b);
}

#reverse!Object

15.2.12.5.25



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
# File 'mruby/src/array.c', line 482

static mrb_value
mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int len = ARY_LEN(a);

  if (len > 1) {
    mrb_value *p1, *p2;

    ary_modify(mrb, a);
    p1 = ARY_PTR(a);
    p2 = p1 + len - 1;

    while (p1 < p2) {
      mrb_value tmp = *p1;
      *p1++ = *p2;
      *p2-- = tmp;
    }
  }
  return self;
}

#reverse_each(&block) ⇒ Object

for efficiency



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

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

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

#rindexObject

15.2.12.5.26



1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
# File 'mruby/src/array.c', line 1144

static mrb_value
mrb_ary_rindex_m(mrb_state *mrb, mrb_value self)
{
  mrb_value obj = mrb_get_arg1(mrb);
  mrb_int i, len;

  for (i = RARRAY_LEN(self) - 1; i >= 0; i--) {
    if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
      return mrb_int_value(mrb, i);
    }
    if (i > (len = RARRAY_LEN(self))) {
      i = len;
    }
  }
  return mrb_nil_value();
}

#rotate(count = 1) ⇒ Array

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

Returns:



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 252

static mrb_value
mrb_ary_rotate(mrb_state *mrb, mrb_value self)
{
  mrb_int count=1;
  mrb_get_args(mrb, "|i", &count);

  mrb_value ary = mrb_ary_new(mrb);
  mrb_int len = RARRAY_LEN(self);
  mrb_value *p = RARRAY_PTR(self);
  mrb_int idx;

  if (len <= 0) return ary;
  if (count < 0) {
    idx = len - (~count % len) - 1;
  }
  else {
    idx = count % len;
  }
  for (mrb_int i = 0; i<len; i++) {
    mrb_ary_push(mrb, ary, p[idx++]);
    if (idx == len) idx = 0;
  }
  return ary;
}

#rotate!(count = 1) ⇒ Array

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

Returns:



303
304
305
306
307
308
309
310
311
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
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 303

static mrb_value
mrb_ary_rotate_bang(mrb_state *mrb, mrb_value self)
{
  mrb_int count=1;
  mrb_get_args(mrb, "|i", &count);

  struct RArray *a = mrb_ary_ptr(self);
  mrb_int len = ARY_LEN(a);
  mrb_value *p = ARY_PTR(a);
  mrb_int idx;

  mrb_ary_modify(mrb, a);
  if (len == 0 || count == 0) return self;
  if (count == 1) {
    mrb_value v = p[0];
    for (mrb_int i=1; i<len; i++) {
      p[i-1] = p[i];
    }
    p[len-1] = v;
    return self;
  }
  if (count < 0) {
    idx = len - (~count % len) - 1;
  }
  else {
    idx = count % len;
  }
  /* e.g. [1,2,3,4,5].rotate!(2) -> [3,4,5,1,2] */
  /* first, reverse the whole array */
  /* [1,2,3,4,5] -> [5,4,3,2,1] */
  rev(p, 0, len);
  /* then, re-reverse part before idx */
  /* [5,4,3,2,1] -> [3,4,5,2,1] */
  /*        ^idx     ~~~~~      */
  rev(p, 0, len-idx);
  /* finally, re-reverse part after idx */
  /* [3,4,5,2,1] -> [3,4,5,1,2] */
  /*        ^idx           ~~~  */
  rev(p, len-idx, len);
  return self;
}

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


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

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

#shiftObject

15.2.12.5.27



612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
# File 'mruby/src/array.c', line 612

static mrb_value
mrb_ary_shift_m(mrb_state *mrb, mrb_value self)
{
  mrb_int n;

  if (mrb_get_args(mrb, "|i", &n) == 0) {
    return mrb_ary_shift(mrb, self);
  }

  struct RArray *a = mrb_ary_ptr(self);
  mrb_int len = ARY_LEN(a);
  mrb_value val;

  ary_modify_check(mrb, a);
  if (len == 0 || n == 0) return mrb_ary_new(mrb);
  if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array shift");
  if (n > len) n = len;
  val = mrb_ary_new_from_values(mrb, n, ARY_PTR(a));
  if (ARY_SHARED_P(a)) {
  L_SHIFT:
    a->as.heap.ptr+=n;
    a->as.heap.len-=n;
    return val;
  }
  if (len > ARY_SHIFT_SHARED_MIN) {
    ary_make_shared(mrb, a);
    goto L_SHIFT;
  }
  else if (len == n) {
    ARY_SET_LEN(a, 0);
  }
  else {
    mrb_value *ptr = ARY_PTR(a);
    mrb_int size = len-n;

    while (size--) {
      *ptr = *(ptr+n);
      ptr++;
    }
    ARY_SET_LEN(a, len-n);
  }
  return val;
}

#sizeObject

15.2.12.5.28



1186
1187
1188
1189
1190
1191
1192
# File 'mruby/src/array.c', line 1186

static mrb_value
mrb_ary_size(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);

  return mrb_int_value(mrb, ARY_LEN(a));
}

#[](index) ⇒ Object? #[](start, length) ⇒ Array? #[](range) ⇒ Array? #slice(index) ⇒ Object? #slice(start, length) ⇒ Array? #slice(range) ⇒ Array?

Element Reference — Returns the element at index, or returns a subarray starting at the start index and continuing for length elements, or returns a subarray specified by range of indices.

Negative indices count backward from the end of the array (-1 is the last element). For start and range cases the starting index is just before an element. Additionally, an empty array is returned when the starting index for an element range is at the end of the array.

Returns nil if the index (or starting index) are out of range.

a = [ “a”, “b”, “c”, “d”, “e” ] a => “b” a => [“b”, “c”] a => [“b”, “c”, “d”]

Overloads:



950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
# File 'mruby/src/array.c', line 950

static mrb_value
mrb_ary_aget(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int i;
  mrb_int len, alen;
  mrb_value index;

  if (mrb_get_argc(mrb) == 1) {
    index = mrb_get_arg1(mrb);
    switch (mrb_type(index)) {
      /* a[n..m] */
    case MRB_TT_RANGE:
      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
        return ary_subseq(mrb, a, i, len);
      }
      else {
        return mrb_nil_value();
      }
    case MRB_TT_INTEGER:
      return mrb_ary_ref(mrb, self, mrb_integer(index));
    default:
      return mrb_ary_ref(mrb, self, aget_index(mrb, index));
    }
  }

  mrb_get_args(mrb, "oi", &index, &len);
  i = aget_index(mrb, index);
  alen = ARY_LEN(a);
  if (i < 0) i += alen;
  if (i < 0 || alen < i) return mrb_nil_value();
  if (len < 0) return mrb_nil_value();
  if (alen == i) return mrb_ary_new(mrb);
  if (len > alen - i) len = alen - i;

  return ary_subseq(mrb, a, i, len);
}

#slice!(index) ⇒ Object? #slice!(start, length) ⇒ Array? #slice!(range) ⇒ Array?

Deletes the element(s) given by an index (optionally up to length elements) or by a range.

Returns the deleted object (or objects), or nil if the index is out of range.

a = [ "a", "b", "c" ]
a.slice!(1)     #=> "b"
a               #=> ["a", "c"]
a.slice!(-1)    #=> "c"
a               #=> ["a"]
a.slice!(100)   #=> nil
a               #=> ["a"]

Overloads:



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 136

static mrb_value
mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  mrb_int i, j, len, alen;
  mrb_value *ptr;
  mrb_value ary;

  mrb_ary_modify(mrb, a);

  if (mrb_get_argc(mrb) == 1) {
    mrb_value index = mrb_get_arg1(mrb);

    if (mrb_type(index) == MRB_TT_RANGE) {
      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
        goto delete_pos_len;
      }
      return mrb_nil_value();
    }
    return mrb_ary_delete_at(mrb, self);
  }

  mrb_get_args(mrb, "ii", &i, &len);
 delete_pos_len:
  alen = ARY_LEN(a);
  if (i < 0) i += alen;
  if (i < 0 || alen < i) return mrb_nil_value();
  if (len < 0) return mrb_nil_value();
  if (alen == i) return mrb_ary_new(mrb);
  if (len > alen - i) len = alen - i;

  ptr = ARY_PTR(a) + i;
  ary = mrb_ary_new_from_values(mrb, len, ptr);

  for (j = i; j < alen - len; j++) {
    *ptr = *(ptr+len);
    ptr++;
  }

  mrb_ary_resize(mrb, self, alen - len);
  return ary;
}

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



301
302
303
# File 'mruby/mrblib/array.rb', line 301

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

#sort!(&block) ⇒ Object

call-seq:

array.sort! -> self
array.sort! {|a, b| ... } -> self

Sort all elements and replace self with these elements.



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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'mruby/mrblib/array.rb', line 230

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_aObject Also known as: entries

call-seq:

array.to_a -> self

Returns self, no need to convert.



310
311
312
# File 'mruby/mrblib/array.rb', line 310

def to_a
  self
end

#to_h(&blk) ⇒ Object

call-seq:

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

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

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


885
886
887
888
889
890
891
892
893
894
# File 'mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 885

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


856
857
858
859
860
861
862
863
864
865
866
867
868
869
# File 'mruby/mrbgems/mruby-array-ext/mrblib/array.rb', line 856

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

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

#uniq!(&block) ⇒ Object

call-seq:

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

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

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


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File '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

#unshift(*objects) ⇒ self Also known as: prepend

Prepends the given objects to self:

a = [:foo, 'bar', 2]
a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]

Array#prepend is an alias for Array#unshift.

Related: #push, #pop, #shift.

Returns:

  • (self)


702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
# File 'mruby/src/array.c', line 702

static mrb_value
mrb_ary_unshift_m(mrb_state *mrb, mrb_value self)
{
  struct RArray *a = mrb_ary_ptr(self);
  const mrb_value *vals;
  mrb_value *ptr;
  mrb_int alen, len;

  alen = mrb_get_argc(mrb);
  vals = mrb_get_argv(mrb);
  if (alen == 0) {
    ary_modify_check(mrb, a);
    return self;
  }
  len = ARY_LEN(a);
  if (alen > ARY_MAX_SIZE - len) {
    ary_too_big(mrb);
  }
  if (ARY_SHARED_P(a)
      && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */
      && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= alen) /* there's room for unshifted item */ {
    ary_modify_check(mrb, a);
    a->as.heap.ptr -= alen;
    ptr = a->as.heap.ptr;
  }
  else {
    mrb_bool same = vals == ARY_PTR(a);
    ary_modify(mrb, a);
    if (ARY_CAPA(a) < len + alen)
      ary_expand_capa(mrb, a, len + alen);
    ptr = ARY_PTR(a);
    value_move(ptr + alen, ptr, len);
    if (same) vals = ptr;
  }
  array_copy(ptr, vals, alen);
  ARY_SET_LEN(a, len+alen);
  while (alen--) {
    mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[alen]);
  }

  return self;
}

#values_atObject



104
105
106
107
108
109
110
111
# File 'mruby/mrbgems/mruby-array-ext/src/array.c', line 104

static mrb_value
mrb_ary_values_at(mrb_state *mrb, mrb_value self)
{
  mrb_int argc = mrb_get_argc(mrb);
  const mrb_value *argv = mrb_get_argv(mrb);

  return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, ary_ref);
}

#|(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 '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