Spec-Zone.ru › Ruby 3

класс Array

Родитель:
Объект
Включенные модули:
Enumerable

Массив — это упорядоченная коллекция объектов с целочисленными индексами, называемыми элементами. Любой объект может быть элементом массива.

Индексы массива

Индексация массивов начинается с 0, как в C или Java.

Положительный индекс — это смещение от первого элемента:

  • Индекс 0 указывает на первый элемент.

  • Индекс 1 указывает на второй элемент.

  • …

Отрицательный индекс — это смещение назад от конца массива:

  • Индекс -1 указывает на последний элемент.

  • Индекс -2 указывает на предпоследний элемент.

  • …

Неотрицательный индекс входит в диапазон, если он меньше размера массива. Для массива из 3 элементов:

  • Индексы от 0 до 2 входят в диапазон.

  • Индекс 3 выходит за пределы диапазона.

Отрицательный индекс входит в диапазон, если его абсолютное значение не больше размера массива. Для массива из 3 элементов:

  • Индексы от -1 до -3 входят в диапазон.

  • Индекс -4 выходит за пределы диапазона.

Создание массивов

Новый массив можно создать, используя литеральный конструктор []. Массивы могут содержать разные типы объектов. Например, массив ниже содержит Integer, String и число с плавающей точкой:

ary = [1, "two", 3.0] #=> [1, "two", 3.0]

Массив также можно создать, явно вызвав Array.new с нулевым, одним (начальный размер Array) или двумя аргументами (начальный размер и объект по умолчанию).

ary = Array.new    #=> []
Array.new(3)       #=> [nil, nil, nil]
Array.new(3, true) #=> [true, true, true]

Обратите внимание, что второй аргумент заполняет массив ссылками на тот же объект. Поэтому он рекомендуется только в тех случаях, когда вам нужно создать массивы с неизменяемыми объектами, такими как символы, числа, true или false.

Для создания массива с отдельными объектами можно передать блок вместо этого. Этот метод безопасен для использования с изменяемыми объектами, такими как хэши, строки или другие массивы:

Array.new(4) {Hash.new}    #=> [{}, {}, {}, {}]
Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]

Это также быстрый способ создания многомерных массивов:

empty_table = Array.new(3) {Array.new(3)}
#=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]

Массив также можно создать, используя метод Array(), предоставляемый Kernel, который пытается вызвать to_ary, а затем to_a на своем аргументе.

Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]

Примеры использования

Помимо методов, включенных через модуль Enumerable, класс Array имеет собственные методы для доступа, поиска и других манипуляций с массивами.

Некоторые из наиболее распространённых показаны ниже.

Доступ к элементам

Элементы массива можно получить, используя метод Array#[]. Он может принимать один целочисленный аргумент (числовой индекс), пару аргументов (начало и длина) или диапазон. Отрицательные индексы начинаются с отсчёта с конца, где -1 — последний элемент.

arr = [1, 2, 3, 4, 5, 6]
arr[2]    #=> 3
arr[100]  #=> nil
arr[-3]   #=> 4
arr[2, 3] #=> [3, 4, 5]
arr[1..4] #=> [2, 3, 4, 5]
arr[1..-3] #=> [2, 3, 4]

Другой способ доступа к элементу массива — использование метода at

arr.at(0) #=> 1

Метод slice работает так же, как и Array#[].

Чтобы вызвать ошибку для индексов вне границ массива или предоставить значение по умолчанию в этом случае, можно использовать fetch.

arr = ['a', 'b', 'c', 'd', 'e', 'f']
arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
arr.fetch(100, "oops") #=> "oops"

Специальные методы first и last соответственно возвращают первый и последний элементы массива.

arr.first #=> 1
arr.last  #=> 6

Чтобы вернуть первые n элементов массива, используйте take

arr.take(3) #=> [1, 2, 3]

drop делает обратное take, возвращая элементы после того, как n элементов были удалены:

arr.drop(3) #=> [4, 5, 6]

Получение информации об Array

Массивы всегда отслеживают свою длину. Чтобы узнать количество элементов в массиве, используйте length, count или size.

browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
browsers.length #=> 5
browsers.count #=> 5

Чтобы проверить, содержит ли массив какие-либо элементы вообще

browsers.empty? #=> false

Чтобы проверить, включён ли определённый элемент в массив

browsers.include?('Konqueror') #=> false

Добавление элементов в массивы

Элементы можно добавить в конец массива, используя push или <<

arr = [1, 2, 3, 4]
arr.push(5) #=> [1, 2, 3, 4, 5]
arr << 6    #=> [1, 2, 3, 4, 5, 6]

unshift добавит новый элемент в начало массива.

arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]

С помощью insert можно добавить новый элемент в массив в любом месте.

arr.insert(3, 'apple')  #=> [0, 1, 2, 'apple', 3, 4, 5, 6]

Используя метод insert, можно вставить несколько значений одновременно:

arr.insert(3, 'orange', 'pear', 'grapefruit')
#=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]

Удаление элементов из Array

Метод pop удаляет последний элемент массива и возвращает его:

arr =  [1, 2, 3, 4, 5, 6]
arr.pop #=> 6
arr #=> [1, 2, 3, 4, 5]

Чтобы получить и одновременно удалить первый элемент, используйте shift:

arr.shift #=> 1
arr #=> [2, 3, 4, 5]

Чтобы удалить элемент по определённому индексу:

arr.delete_at(2) #=> 4
arr #=> [2, 3, 5]

Чтобы удалить определённый элемент где-либо в массиве, используйте delete:

arr = [1, 2, 2, 3]
arr.delete(2) #=> 2
arr #=> [1,3]

Полезный метод, если вам нужно удалить nil значения из массива, — compact:

arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
arr.compact  #=> ['foo', 0, 'bar', 7, 'baz']
arr          #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
arr          #=> ['foo', 0, 'bar', 7, 'baz']

Ещё одна распространённая потребность — удаление дублирующих элементов из массива.

Он имеет неразрушающий метод uniq и разрушающий метод uniq!

arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]

Итерация по массивам

Как и все классы, включающие модуль Enumerable, Array имеет метод each, который определяет, какие элементы следует перебирать и как. В случае each массива все элементы экземпляра Array передаются предоставленному блоку последовательно.

Обратите внимание, что эта операция не изменяет массив.

arr = [1, 2, 3, 4, 5]
arr.each {|a| print a -= 10, " "}
# prints: -9 -8 -7 -6 -5
#=> [1, 2, 3, 4, 5]

Ещё один иногда полезный итератор — reverse_each, который перебирает элементы массива в обратном порядке.

words = %w[first second third fourth fifth sixth]
str = ""
words.reverse_each {|word| str += "#{word} "}
p str #=> "sixth fifth fourth third second first "

Метод map можно использовать для создания нового массива на основе исходного массива, но с изменёнными значениями, определёнными в предоставленном блоке:

arr.map {|a| 2*a}     #=> [2, 4, 6, 8, 10]
arr                   #=> [1, 2, 3, 4, 5]
arr.map! {|a| a**2}   #=> [1, 4, 9, 16, 25]
arr                   #=> [1, 4, 9, 16, 25]

Выбор элементов из Array

Элементы массива можно выбирать по критериям, определённым в блоке. Выбор может быть разрушающим или неразрушающим. В то время как разрушающие операции изменят массив, на котором они были вызваны, неразрушающие методы обычно возвращают новый массив с выбранными элементами, но оставляют исходный массив неизменным.

Неразрушающий выбор

arr = [1, 2, 3, 4, 5, 6]
arr.select {|a| a > 3}       #=> [4, 5, 6]
arr.reject {|a| a < 3}       #=> [3, 4, 5, 6]
arr.drop_while {|a| a < 4}   #=> [4, 5, 6]
arr                          #=> [1, 2, 3, 4, 5, 6]

Разрушающий выбор

select! и reject! — соответствующие разрушающие методы для select и reject

Подобно select и reject, delete_if и keep_if дают точно обратные результаты при передаче одного и того же блока:

arr.delete_if {|a| a < 4}   #=> [4, 5, 6]
arr                         #=> [4, 5, 6]

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

для pack.c

Методы публичного класса

[](*args) Показать исходный код
static VALUE
rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
{
    VALUE ary = ary_new(klass, argc);
    if (argc > 0 && argv) {
        ary_memcpy(ary, 0, argc, argv);
        ARY_SET_LEN(ary, argc);
    }

    return ary;
}

Возвращает новый массив, заполненный заданными объектами.

Array.[]( 1, 'a', /^A/)  # => [1, "a", /^A/]
Array[ 1, 'a', /^A/ ]    # => [1, "a", /^A/]
[ 1, 'a', /^A/ ]         # => [1, "a", /^A/]
new → new_empty_array Показать исходный код
new(array) → new_array
new(size) → new_array
new(size, default_value) → new_array
new(size) {|index| ... } → new_array
static VALUE
rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
{
    long len;
    VALUE size, val;

    rb_ary_modify(ary);
    if (argc == 0) {
        if (ARY_OWNS_HEAP_P(ary) && ARY_HEAP_PTR(ary) != NULL) {
            ary_heap_free(ary);
        }
        rb_ary_unshare_safe(ary);
        FL_SET_EMBED(ary);
        ARY_SET_EMBED_LEN(ary, 0);
        if (rb_block_given_p()) {
            rb_warning("given block not used");
        }
        return ary;
    }
    rb_scan_args(argc, argv, "02", &size, &val);
    if (argc == 1 && !FIXNUM_P(size)) {
        val = rb_check_array_type(size);
        if (!NIL_P(val)) {
            rb_ary_replace(ary, val);
            return ary;
        }
    }

    len = NUM2LONG(size);
    /* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
    if (len < 0) {
        rb_raise(rb_eArgError, "negative array size");
    }
    if (len > ARY_MAX_SIZE) {
        rb_raise(rb_eArgError, "array size too big");
    }
    /* recheck after argument conversion */
    rb_ary_modify(ary);
    ary_resize_capa(ary, len);
    if (rb_block_given_p()) {
        long i;

        if (argc == 2) {
            rb_warn("block supersedes default value argument");
        }
        for (i=0; i<len; i++) {
            rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
            ARY_SET_LEN(ary, i + 1);
        }
    }
    else {
        ary_memfill(ary, 0, len, val);
        ARY_SET_LEN(ary, len);
    }
    return ary;
}

Возвращает новый массив.

Без блока и без аргументов возвращает новый пустой объект массива.

Без блока и с одним аргументом типа массив array, возвращает новый массив, сформированный из array:

a = Array.new([:foo, 'bar', 2])
a.class # => Array
a # => [:foo, "bar", 2]

Без блока и с одним целым аргументом size, возвращает новый массив заданного размера, элементы которого все nil:

a = Array.new(3)
a # => [nil, nil, nil]

Без блока и с аргументами size и default_value, возвращает массив заданного размера; каждый элемент имеет то же значение default_value:

a = Array.new(3, 'x')
a # => ['x', 'x', 'x']

С блоком и аргументом size, возвращает массив заданного размера; блок вызывается с каждым последующим целым числом index; элемент для этого index — значение, возвращаемое блоком:

a = Array.new(3) {|index| "Element #{index}" }
a # => ["Element 0", "Element 1", "Element 2"]

Вызывает исключение ArgumentError, если size отрицательно.

С блоком и без аргументов или с одним аргументом 0, игнорирует блок и возвращает новый пустой массив.

try_convert(object) → object, new_array, or nil Показать исходный код
static VALUE
rb_ary_s_try_convert(VALUE dummy, VALUE ary)
{
    return rb_check_array_type(ary);
}

Если object является объектом массива, возвращает object.

В противном случае, если object отвечает на :to_ary, вызывает object.to_ary и возвращает результат.

Возвращает nil, если object не отвечает на :to_ary

Вызывает исключение, если object.to_ary не возвращает объект массива.

Методы публичного экземпляра

array & other_array → new_array Показать исходный код
static VALUE
rb_ary_and(VALUE ary1, VALUE ary2)
{
    VALUE hash, ary3, v;
    st_data_t vv;
    long i;

    ary2 = to_ary(ary2);
    ary3 = rb_ary_new();
    if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;

    if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
        for (i=0; i<RARRAY_LEN(ary1); i++) {
            v = RARRAY_AREF(ary1, i);
            if (!rb_ary_includes_by_eql(ary2, v)) continue;
            if (rb_ary_includes_by_eql(ary3, v)) continue;
            rb_ary_push(ary3, v);
        }
        return ary3;
    }

    hash = ary_make_hash(ary2);

    for (i=0; i<RARRAY_LEN(ary1); i++) {
        v = RARRAY_AREF(ary1, i);
        vv = (st_data_t)v;
        if (rb_hash_stlike_delete(hash, &vv, 0)) {
            rb_ary_push(ary3, v);
        }
    }
    ary_recycle_hash(hash);

    return ary3;
}

Возвращает новый массив, содержащий каждый элемент, найденный как в array, так и в массиве other_array; дубликаты опускаются; элементы сравниваются с помощью eql?:

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

Сохраняет порядок из array:

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

Связанно с: Array#intersection.

array * n → new_array Показать исходный код
array * string_separator → new_string
static VALUE
rb_ary_times(VALUE ary, VALUE times)
{
    VALUE ary2, tmp;
    const VALUE *ptr;
    long t, len;

    tmp = rb_check_string_type(times);
    if (!NIL_P(tmp)) {
        return rb_ary_join(ary, tmp);
    }

    len = NUM2LONG(times);
    if (len == 0) {
        ary2 = ary_new(rb_cArray, 0);
        goto out;
    }
    if (len < 0) {
        rb_raise(rb_eArgError, "negative argument");
    }
    if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
        rb_raise(rb_eArgError, "argument too big");
    }
    len *= RARRAY_LEN(ary);

    ary2 = ary_new(rb_cArray, len);
    ARY_SET_LEN(ary2, len);

    ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
    t = RARRAY_LEN(ary);
    if (0 < t) {
        ary_memcpy(ary2, 0, t, ptr);
        while (t <= len/2) {
            ary_memcpy(ary2, t, t, RARRAY_CONST_PTR_TRANSIENT(ary2));
            t *= 2;
        }
        if (t < len) {
            ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR_TRANSIENT(ary2));
        }
    }
  out:
    return ary2;
}

Когда предоставляется целое число n, возвращает новый массив, созданный путём конкатенации n копий self:

a = ['x', 'y']
a * 3 # => ["x", "y", "x", "y", "x", "y"]

Когда предоставляется строковый аргумент string_separator, эквивалентно array.join(string_separator):

[0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
array + other_array → new_array Показать исходный код
VALUE
rb_ary_plus(VALUE x, VALUE y)
{
    VALUE z;
    long len, xlen, ylen;

    y = to_ary(y);
    xlen = RARRAY_LEN(x);
    ylen = RARRAY_LEN(y);
    len = xlen + ylen;
    z = rb_ary_new2(len);

    ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x));
    ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
    ARY_SET_LEN(z, len);
    return z;
}

Возвращает новый массив, содержащий все элементы array, за которыми следуют все элементы other_array:

a = [0, 1] + [2, 3]
a # => [0, 1, 2, 3]

Связанно с: concat.

array - other_array → new_array Показать исходный код
static VALUE
rb_ary_diff(VALUE ary1, VALUE ary2)
{
    VALUE ary3;
    VALUE hash;
    long i;

    ary2 = to_ary(ary2);
    ary3 = rb_ary_new();

    if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
        for (i=0; i<RARRAY_LEN(ary1); i++) {
            VALUE elt = rb_ary_elt(ary1, i);
            if (rb_ary_includes_by_eql(ary2, elt)) continue;
            rb_ary_push(ary3, elt);
        }
        return ary3;
    }

    hash = ary_make_hash(ary2);
    for (i=0; i<RARRAY_LEN(ary1); i++) {
        if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
        rb_ary_push(ary3, rb_ary_elt(ary1, i));
    }
    ary_recycle_hash(hash);
    return ary3;
}

Возвращает новый массив, содержащий только те элементы из array, которые не найдены в массиве other_array; элементы сравниваются с помощью eql?; порядок из array сохраняется:

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

Связанно с: Array#difference.

array << object → self Показать исходный код
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
    long idx = RARRAY_LEN((ary_verify(ary), ary));
    VALUE target_ary = ary_ensure_room_for_push(ary, 1);
    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
        RB_OBJ_WRITE(target_ary, &ptr[idx], item);
    });
    ARY_SET_LEN(ary, idx + 1);
    ary_verify(ary);
    return ary;
}

Добавляет object в self; возвращает self:

a = [:foo, 'bar', 2]
a << :baz # => [:foo, "bar", 2, :baz]

Добавляет object как один элемент, даже если это другой массив:

a = [:foo, 'bar', 2]
a1 = a << [3, 4]
a1 # => [:foo, "bar", 2, [3, 4]]
array <=> other_array → -1, 0, or 1 Показать исходный код
VALUE
rb_ary_cmp(VALUE ary1, VALUE ary2)
{
    long len;
    VALUE v;

    ary2 = rb_check_array_type(ary2);
    if (NIL_P(ary2)) return Qnil;
    if (ary1 == ary2) return INT2FIX(0);
    v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
    if (v != Qundef) return v;
    len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
    if (len == 0) return INT2FIX(0);
    if (len > 0) return INT2FIX(1);
    return INT2FIX(-1);
}

Возвращает -1, 0 или 1 в зависимости от того, меньше ли self, равно ли, или больше ли, чем other_array. Для каждого индекса i в self, вычисляется result = self[i] <=> other_array[i].

Возвращает -1, если любой результат равен -1:

[0, 1, 2] <=> [0, 1, 3] # => -1

Возвращает 1, если любой результат равен 1:

[0, 1, 2] <=> [0, 1, 1] # => 1

Когда все результаты равны нулю:

  • Возвращает -1, если array меньше, чем other_array:

    [0, 1, 2] <=> [0, 1, 2, 3] # => -1
    
  • Возвращает 1, если array больше, чем other_array:

    [0, 1, 2] <=> [0, 1] # => 1
    
  • Возвращает 0, если array и other_array одинаковой длины:

    [0, 1, 2] <=> [0, 1, 2] # => 0
    
array == other_array → true or false Показать исходный код
static VALUE
rb_ary_equal(VALUE ary1, VALUE ary2)
{
    if (ary1 == ary2) return Qtrue;
    if (!RB_TYPE_P(ary2, T_ARRAY)) {
        if (!rb_respond_to(ary2, idTo_ary)) {
            return Qfalse;
        }
        return rb_equal(ary2, ary1);
    }
    if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
    if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
    return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
}

Возвращает true, если оба array.size == other_array.size и для каждого индекса i в array, array[i] == other_array[i]:

a0 = [:foo, 'bar', 2]
a1 = [:foo, 'bar', 2.0]
a1 == a0 # => true
[] == [] # => true

В противном случае, возвращает false.

Этот метод отличается от метода Array#eql?, который сравнивает элементы с использованием Object#eql?.

array[index] → object or nil Показать исходный код
array[start, length] → object or nil
array[range] → object or nil
array[aseq] → object or nil
VALUE
rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
{
    rb_check_arity(argc, 1, 2);
    if (argc == 2) {
        return rb_ary_aref2(ary, argv[0], argv[1]);
    }
    return rb_ary_aref1(ary, argv[0]);
}

Возвращает элементы из self; не изменяет self.

Если передан один целочисленный аргумент index, возвращает элемент с смещением index:

a = [:foo, 'bar', 2]
a[0] # => :foo
a[2] # => 2
a # => [:foo, "bar", 2]

Если index отрицательное, считает относительно конца self:

a = [:foo, 'bar', 2]
a[-1] # => 2
a[-2] # => "bar"

Если index вне диапазона, возвращает nil.

Если переданы два целочисленных аргумента start и length, возвращает новый массив размера length содержащий последовательные элементы, начиная со смещения start:

a = [:foo, 'bar', 2]
a[0, 2] # => [:foo, "bar"]
a[1, 2] # => ["bar", 2]

Если start + length больше, чем self.length, возвращает все элементы от смещения start до конца:

a = [:foo, 'bar', 2]
a[0, 4] # => [:foo, "bar", 2]
a[1, 3] # => ["bar", 2]
a[2, 2] # => [2]

Если start == self.size и length >= 0 отрицательны, возвращает пустой массив.

Если length отрицательное, возвращает nil.

Если в качестве аргумента передан диапазон range, обрабатывает range.min как start выше и range.size как length выше:

a = [:foo, 'bar', 2]
a[0..1] # => [:foo, "bar"]
a[1..2] # => ["bar", 2]

Особый случай: Если range.start == a.size, возвращает новый пустой массив.

Если range.end отрицательное, вычисляет конечный индекс от конца:

a = [:foo, 'bar', 2]
a[0..-1] # => [:foo, "bar", 2]
a[0..-2] # => [:foo, "bar"]
a[0..-3] # => [:foo]

Если range.start отрицательное, вычисляет начальный индекс от конца:

a = [:foo, 'bar', 2]
a[-1..2] # => [2]
a[-2..2] # => ["bar", 2]
a[-3..2] # => [:foo, "bar", 2]

Если range.start больше размера массива, возвращает nil.

a = [:foo, 'bar', 2]
a[4..1] # => nil
a[4..0] # => nil
a[4..-1] # => nil

Если передан один аргумент типа Enumerator::ArithmeticSequence aseq, возвращает массив Array элементов, соответствующих индексам, сгенерированным последовательностью.

a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..).step(2)] # => ["data1", "data2", "data3"]

В отличие от среза с диапазоном, если начало или конец арифметической последовательности больше размера массива, выбрасывается RangeError.

a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..11).step(2)]
# RangeError (((1..11).step(2)) out of range)
a[(7..).step(2)]
# RangeError (((7..).step(2)) out of range)

Если передан один аргумент, и его тип не из перечисленных, пытается преобразовать его в Integer, и поднимает ошибку, если это невозможно:

a = [:foo, 'bar', 2]
# Raises TypeError (no implicit conversion of Symbol into Integer):
a[:foo]

Array#slice является псевдонимом для Array#[].

Также алиасы: slice
END_OF_DOCUMENT_MARKER
array[index] = object → object Показать исходный код
array[start, length] = object → object
array[range] = object → object
static VALUE
rb_ary_aset(int argc, VALUE *argv, VALUE ary)
{
    long offset, beg, len;

    rb_check_arity(argc, 2, 3);
    rb_ary_modify_check(ary);
    if (argc == 3) {
        beg = NUM2LONG(argv[0]);
        len = NUM2LONG(argv[1]);
        return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
    }
    if (FIXNUM_P(argv[0])) {
        offset = FIX2LONG(argv[0]);
        return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
    }
    if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
        /* check if idx is Range */
        return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
    }

    offset = NUM2LONG(argv[0]);
    return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}

Присваивает элементы в self; возвращает заданный object.

Когда передан целочисленный аргумент index, присваивает object элементу в self.

Если index неотрицательно, присваивает object элемент с смещением index:

a = [:foo, 'bar', 2]
a[0] = 'foo' # => "foo"
a # => ["foo", "bar", 2]

Если index больше self.length, расширяет массив:

a = [:foo, 'bar', 2]
a[7] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]

Если index отрицательно, считает назад от конца массива:

a = [:foo, 'bar', 2]
a[-1] = 'two' # => "two"
a # => [:foo, "bar", "two"]

Когда заданы целочисленные аргументы start и length и object не является массивом, удаляет length - 1 элементов, начиная со смещения start, и присваивает object со смещением start:

a = [:foo, 'bar', 2]
a[0, 2] = 'foo' # => "foo"
a # => ["foo", 2]

Если start отрицательно, считает назад от конца массива:

a = [:foo, 'bar', 2]
a[-2, 2] = 'foo' # => "foo"
a # => [:foo, "foo"]

Если start неотрицательно и выходит за пределы массива ( >= self.size), расширяет массив с nil, присваивает object со смещением start, и игнорирует length:

a = [:foo, 'bar', 2]
a[6, 50] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, "foo"]

Если length равно нулю, сдвигает элементы со смещения start и далее и присваивает object со смещением start:

a = [:foo, 'bar', 2]
a[1, 0] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]

Если length слишком велико для существующего массива, не расширяет массив:

a = [:foo, 'bar', 2]
a[1, 5] = 'foo' # => "foo"
a # => [:foo, "foo"]

Когда задан аргумент диапазона range и object является массивом, удаляет length - 1 элементов, начиная со смещения start, и присваивает object со смещением start:

a = [:foo, 'bar', 2]
a[0..1] = 'foo' # => "foo"
a # => ["foo", 2]

если range.begin отрицательно, считает назад от конца массива:

a = [:foo, 'bar', 2]
a[-2..2] = 'foo' # => "foo"
a # => [:foo, "foo"]

Если длина массива меньше range.begin, присваивает object со смещением range.begin, и игнорирует length:

a = [:foo, 'bar', 2]
a[6..50] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, "foo"]

Если range.end равно нулю, сдвигает элементы со смещения start и далее и присваивает object со смещением start:

a = [:foo, 'bar', 2]
a[1..0] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]

Если range.end отрицательно, присваивает object со смещением start, сохраняет range.end.abs -1 элементы после этого и удаляет те, что за пределами:

a = [:foo, 'bar', 2]
a[1..-1] = 'foo' # => "foo"
a # => [:foo, "foo"]
a = [:foo, 'bar', 2]
a[1..-2] = 'foo' # => "foo"
a # => [:foo, "foo", 2]
a = [:foo, 'bar', 2]
a[1..-3] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]
a = [:foo, 'bar', 2]

Если range.end слишком велико для существующего массива, заменяет элементы массива, но не расширяет массив значениями nil:

a = [:foo, 'bar', 2]
a[1..5] = 'foo' # => "foo"
a # => [:foo, "foo"]
abbrev(pattern = nil) Показать исходный код
# File lib/abbrev.rb, line 129
def abbrev(pattern = nil)
  Abbrev::abbrev(self, pattern)
end

Вычисляет множество недвусмысленных сокращений для строк в self.

require 'abbrev'
%w{ car cone }.abbrev
#=> {"car"=>"car", "ca"=>"car", "cone"=>"cone", "con"=>"cone", "co"=>"cone"}

Необязательный параметр pattern — это шаблон или строка. Только строки-входы, которые соответствуют шаблону или начинаются со строки, включаются в выходной хэш.

%w{ fast boat day }.abbrev(/^.a/)
#=> {"fast"=>"fast", "fas"=>"fast", "fa"=>"fast", "day"=>"day", "da"=>"day"}

Abbrev.abbrev(%w{car box cone}, "ca")
#=> {"car"=>"car", "ca"=>"car"}

См. также Abbrev.abbrev

all? → true или false Показать исходный код
all? {|element| ... } → true или false
all?(obj) → true или false
static VALUE
rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
{
    long i, len = RARRAY_LEN(ary);

    rb_check_arity(argc, 0, 1);
    if (!len) return Qtrue;
    if (argc) {
        if (rb_block_given_p()) {
            rb_warn("given block not used");
        }
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
        }
    }
    else if (!rb_block_given_p()) {
        for (i = 0; i < len; ++i) {
            if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
        }
    }
    else {
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
        }
    }
    return Qtrue;
}

Возвращает true , если все элементы self удовлетворяют заданному критерию.

Без блока и без аргумента, возвращает true , если self содержит только истинноподобные элементы, false в противном случае:

[0, 1, :foo].all? # => true
[0, nil, 2].all? # => false
[].all? # => true

С блоком и без аргумента, вызывает блок с каждым элементом в self; возвращает true , если блок возвращает только истинноподобные значения, false в противном случае:

[0, 1, 2].all? { |element| element < 3 } # => true
[0, 1, 2].all? { |element| element < 2 } # => false

Если аргумент obj передан, возвращает true , если obj.=== каждый элемент, false в противном случае:

['food', 'fool', 'foot'].all?(/foo/) # => true
['food', 'drink'].all?(/bar/) # => false
[].all?(/foo/) # => true
[0, 0, 0].all?(0) # => true
[0, 1, 2].all?(1) # => false

Связанное: Enumerable#all?

any? → true или false Показать исходный код
any? {|element| ... } → true или false
any?(obj) → true или false
static VALUE
rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
{
    long i, len = RARRAY_LEN(ary);

    rb_check_arity(argc, 0, 1);
    if (!len) return Qfalse;
    if (argc) {
        if (rb_block_given_p()) {
            rb_warn("given block not used");
        }
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
        }
    }
    else if (!rb_block_given_p()) {
        for (i = 0; i < len; ++i) {
            if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;
        }
    }
    else {
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
        }
    }
    return Qfalse;
}

Возвращает true , если любой элемент self удовлетворяет заданному критерию.

Без блока и без аргумента, возвращает true , если self содержит любой истинноподобный элемент, false в противном случае:

[nil, 0, false].any? # => true
[nil, false].any? # => false
[].any? # => false

С блоком и без аргумента, вызывает блок с каждым элементом в self; возвращает true , если блок возвращает любое истинноподобное значение, false в противном случае:

[0, 1, 2].any? {|element| element > 1 } # => true
[0, 1, 2].any? {|element| element > 2 } # => false

Если аргумент obj передан, возвращает true , если obj.=== любой элемент, false в противном случае:

['food', 'drink'].any?(/foo/) # => true
['food', 'drink'].any?(/bar/) # => false
[].any?(/foo/) # => false
[0, 1, 2].any?(1) # => true
[0, 1, 2].any?(3) # => false

Связанное: Enumerable#any?

Добавляет хвостовые элементы.

Добавляет каждый аргумент в objects к self; возвращает self:

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

Добавляет каждый аргумент как один элемент, даже если это другой массив:

a = [:foo, 'bar', 2]
a1 = a.push([:baz, :bat], [:bam, :bad])
a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]

Array#append — псевдоним для Array#push.

Связанное: pop, shift, unshift.

Псевдоним для: push
assoc(obj) → found_array or nil Показать исходный код
VALUE
rb_ary_assoc(VALUE ary, VALUE key)
{
    long i;
    VALUE v;

    for (i = 0; i < RARRAY_LEN(ary); ++i) {
        v = rb_check_array_type(RARRAY_AREF(ary, i));
        if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
            rb_equal(RARRAY_AREF(v, 0), key))
            return v;
    }
    return Qnil;
}

Возвращает первый элемент в self, который является массивом, первый элемент которого == obj:

a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
a.assoc(4) # => [4, 5, 6]

Возвращает nil , если такой элемент не найден.

Связанное: rassoc.

at(index) → object Показать исходный код
VALUE
rb_ary_at(VALUE ary, VALUE pos)
{
    return rb_ary_entry(ary, NUM2LONG(pos));
}

Возвращает элемент по целочисленному смещению index; не изменяет self.

a = [:foo, 'bar', 2]
a.at(0) # => :foo
a.at(2) # => 2
bsearch {|element| ... } → object Показать исходный код
bsearch → new_enumerator
static VALUE
rb_ary_bsearch(VALUE ary)
{
    VALUE index_result = rb_ary_bsearch_index(ary);

    if (FIXNUM_P(index_result)) {
        return rb_ary_entry(ary, FIX2LONG(index_result));
    }
    return index_result;
}

Возвращает элемент из self, выбранный с помощью двоичного поиска. self должен быть отсортирован, но это не проверяется.

Используя двоичный поиск, находит значение из этого массива, которое удовлетворяет заданному условию в O(log n), где n — размер массива.

Существует два режима поиска:

  • Режим поиска минимального значения: блок должен возвращать true или false.

  • Режим поиска любого значения: блок должен возвращать числовое значение.

Блок не должен смешивать режимы, возвращая иногда true или false, а иногда числовое значение, но это не проверяется.

Режим поиска минимального значения

В режиме поиска минимального значения блок всегда возвращает true или false. Дополнительное требование (хотя и не проверяемое) заключается в том, что не существует индексов i и j, таких что:

  • 0 <= i < j <= self.size.

  • Блок возвращает true для self[i] и false для self[j].

В режиме поиска минимального значения метод bsearch возвращает первый элемент, для которого блок возвращает true.

Примеры:

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

Более неформально: блок такой, что все элементы, оцениваемые как false, предшествуют всем элементам, оцениваемым как true.

Эти блоки подходят для режима поиска минимального значения:

a = [0, 4, 7, 10, 12]
a.map {|x| x >= 4 } # => [false, true, true, true, true]
a.map {|x| x >= 6 } # => [false, false, true, true, true]
a.map {|x| x >= -1 } # => [true, true, true, true, true]
a.map {|x| x >= 100 } # => [false, false, false, false, false]

Это не имеет смысла:

a = [0, 4, 7, 10, 12]
a.map {|x| x == 7 } # => [false, false, true, false, false]

Режим поиска любого значения

В режиме поиска любого значения блок всегда возвращает числовое значение. Дополнительное требование (хотя и не проверяемое) заключается в том, что не существует индексов i и j, таких что:

  • 0 <= i < j <= self.size.

  • Блок возвращает отрицательное значение для self[i] и положительное значение для self[j].

  • Блок возвращает отрицательное значение для self[i] и ноль self[j].

  • Блок возвращает ноль для self[i] и положительное значение для self[j].

В режиме поиска любого значения метод bsearch возвращает некоторый элемент, для которого блок возвращает ноль, или nil, если такого элемента не найдено.

Примеры:

a = [0, 4, 7, 10, 12]
a.bsearch {|element| 7 <=> element } # => 7
a.bsearch {|element| -1 <=> element } # => nil
a.bsearch {|element| 5 <=> element } # => nil
a.bsearch {|element| 15 <=> element } # => nil

Более неформально: блок такой, что:

  • Все элементы с положительной оценкой предшествуют всем элементам с нулевой оценкой.

  • Все элементы с положительной оценкой предшествуют всем элементам с отрицательной оценкой.

  • Все элементы с нулевой оценкой предшествуют всем элементам с отрицательной оценкой.

Эти блоки подходят для режима поиска любого значения:

a = [0, 4, 7, 10, 12]
a.map {|element| 7 <=> element } # => [1, 1, 0, -1, -1]
a.map {|element| -1 <=> element } # => [-1, -1, -1, -1, -1]
a.map {|element| 5 <=> element } # => [1, 1, -1, -1, -1]
a.map {|element| 15 <=> element } # => [1, 1, 1, 1, 1]

Это не имеет смысла:

a = [0, 4, 7, 10, 12]
a.map {|element| element <=> 7 } # => [-1, -1, 0, 1, 1]

Возвращает перечислитель, если блок не задан:

a = [0, 4, 7, 10, 12]
a.bsearch # => #<Enumerator: [0, 4, 7, 10, 12]:bsearch>
bsearch_index {|element| ... } → integer or nil Показать исходный код
bsearch_index → new_enumerator
static VALUE
rb_ary_bsearch_index(VALUE ary)
{
    long low = 0, high = RARRAY_LEN(ary), mid;
    int smaller = 0, satisfied = 0;
    VALUE v, val;

    RETURN_ENUMERATOR(ary, 0, 0);
    while (low < high) {
        mid = low + ((high - low) / 2);
        val = rb_ary_entry(ary, mid);
        v = rb_yield(val);
        if (FIXNUM_P(v)) {
            if (v == INT2FIX(0)) return INT2FIX(mid);
            smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
        }
        else if (v == Qtrue) {
            satisfied = 1;
            smaller = 1;
        }
        else if (v == Qfalse || v == Qnil) {
            smaller = 0;
        }
        else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
            const VALUE zero = INT2FIX(0);
            switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
              case 0: return INT2FIX(mid);
              case 1: smaller = 1; break;
              case -1: smaller = 0;
            }
        }
        else {
            rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
                     " (must be numeric, true, false or nil)",
                     rb_obj_class(v));
        }
        if (smaller) {
            high = mid;
        }
        else {
            low = mid + 1;
        }
    }
    if (!satisfied) return Qnil;
    return INT2FIX(low);
}

Ищет self так, как описано в методе bsearch, но возвращает индекс найденного элемента вместо самого элемента.

clear → self Показать исходный код
VALUE
rb_ary_clear(VALUE ary)
{
    rb_ary_modify_check(ary);
    if (ARY_SHARED_P(ary)) {
        if (!ARY_EMBED_P(ary)) {
            rb_ary_unshare(ary);
            FL_SET_EMBED(ary);
            ARY_SET_EMBED_LEN(ary, 0);
        }
    }
    else {
        ARY_SET_LEN(ary, 0);
        if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
            ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
        }
    }
    ary_verify(ary);
    return ary;
}

Удаляет все элементы из self:

a = [:foo, 'bar', 2]
a.clear # => []
static VALUE
rb_ary_collect(VALUE ary)
{
    long i;
    VALUE collect;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    collect = rb_ary_new2(RARRAY_LEN(ary));
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
    }
    return collect;
}

Вызывает блок, если он задан, с каждым элементом self; возвращает новый массив, элементы которого являются возвращаемыми значениями из блока:

a = [:foo, 'bar', 2]
a1 = a.map {|element| element.class }
a1 # => [Symbol, String, Integer]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a1 = a.map
a1 # => #<Enumerator: [:foo, "bar", 2]:map>

Array#collect является псевдонимом для Array#map.

Также алиасируется как: map
static VALUE
rb_ary_collect_bang(VALUE ary)
{
    long i;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    rb_ary_modify(ary);
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
    }
    return ary;
}

Вызывает блок, если он задан, с каждым элементом; заменяет элемент возвращаемым значением блока:

a = [:foo, 'bar', 2]
a.map! { |element| element.class } # => [Symbol, String, Integer]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a1 = a.map!
a1 # => #<Enumerator: [:foo, "bar", 2]:map!>

Array#collect! является псевдонимом для Array#map!.

Также алиасируется как: map!, map!
combination(n) {|element| ... } → self Показать исходный код
combination(n) → new_enumerator
static VALUE
rb_ary_combination(VALUE ary, VALUE num)
{
    long i, n, len;

    n = NUM2LONG(num);
    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
    len = RARRAY_LEN(ary);
    if (n < 0 || len < n) {
        /* yield nothing */
    }
    else if (n == 0) {
        rb_yield(rb_ary_new2(0));
    }
    else if (n == 1) {
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
        }
    }
    else {
        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
        volatile VALUE t0;
        long *stack = ALLOCV_N(long, t0, n+1);

        RBASIC_CLEAR_CLASS(ary0);
        combinate0(len, n, stack, ary0);
        ALLOCV_END(t0);
        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
    }
    return ary;
}

Вызывает блок, если он задан, с комбинациями элементов self; возвращает self. Порядок комбинаций не определен.

Если задан блок и положительное целое число n (0 < n <= self.size) в диапазоне, вызывает блок со всеми комбинациями n-кортежей self.

Пример:

a = [0, 1, 2]
a.combination(2) {|combination| p combination }

Вывод:

[0, 1]
[0, 2]
[1, 2]

Другой пример:

a = [0, 1, 2]
a.combination(3) {|combination| p combination }

Вывод:

[0, 1, 2]

Если n равно нулю, вызывает блок один раз с новым пустым массивом:

a = [0, 1, 2]
a1 = a.combination(0) {|combination| p combination }

Вывод:

[]

Если n выходит за пределы диапазона (отрицательное или больше self.size), блок не вызывается:

a = [0, 1, 2]
a.combination(-1) {|combination| fail 'Cannot happen' }
a.combination(4) {|combination| fail 'Cannot happen' }

Возвращает новый перечислитель, если блок не задан:

a = [0, 1, 2]
a.combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
compact → new_array Показать исходный код
static VALUE
rb_ary_compact(VALUE ary)
{
    ary = rb_ary_dup(ary);
    rb_ary_compact_bang(ary);
    return ary;
}

Возвращает новый массив, содержащий все элементы, отличные от nil из self:

a = [nil, 0, nil, 1, nil, 2, nil]
a.compact # => [0, 1, 2]
compact! → self or nil Показать исходный код
static VALUE
rb_ary_compact_bang(VALUE ary)
{
    VALUE *p, *t, *end;
    long n;

    rb_ary_modify(ary);
    p = t = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary); /* WB: no new reference */
    end = p + RARRAY_LEN(ary);

    while (t < end) {
        if (NIL_P(*t)) t++;
        else *p++ = *t++;
    }
    n = p - RARRAY_CONST_PTR_TRANSIENT(ary);
    if (RARRAY_LEN(ary) == n) {
        return Qnil;
    }
    ary_resize_smaller(ary, n);

    return ary;
}

Удаляет все nil элементы из self.

Возвращает self , если какие-либо элементы были удалены, в противном случае nil.

concat(*other_arrays) → self Показать исходный код
static VALUE
rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
{
    rb_ary_modify_check(ary);

    if (argc == 1) {
        rb_ary_concat(ary, argv[0]);
    }
    else if (argc > 1) {
        int i;
        VALUE args = rb_ary_tmp_new(argc);
        for (i = 0; i < argc; i++) {
            rb_ary_concat(args, argv[i]);
        }
        ary_append(ary, args);
    }

    ary_verify(ary);
    return ary;
}

Добавляет в array все элементы из каждого массива в other_arrays; возвращает self:

a = [0, 1]
a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]
count → an_integer Показать исходный код
count(obj) → an_integer
count {|element| ... } → an_integer
static VALUE
rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
    long i, n = 0;

    if (rb_check_arity(argc, 0, 1) == 0) {
        VALUE v;

        if (!rb_block_given_p())
            return LONG2NUM(RARRAY_LEN(ary));

        for (i = 0; i < RARRAY_LEN(ary); i++) {
            v = RARRAY_AREF(ary, i);
            if (RTEST(rb_yield(v))) n++;
        }
    }
    else {
        VALUE obj = argv[0];

        if (rb_block_given_p()) {
            rb_warn("given block not used");
        }
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
        }
    }

    return LONG2NUM(n);
}

Возвращает количество указанных элементов.

Без аргумента и без блока возвращает общее количество элементов:

[0, 1, 2].count # => 3
[].count # => 0

С аргументом obj, возвращает количество элементов от eql? до obj:

[0, 1, 2, 0].count(0) # => 2
[0, 1, 2].count(3) # => 0

Без аргумента и с заданным блоком, вызывает блок с каждым элементом; возвращает количество элементов, для которых блок возвращает истинное значение:

[0, 1, 2, 3].count {|element| element > 1} # => 2

С аргументом obj и заданным блоком, выдает предупреждение, игнорирует блок и возвращает количество элементов от eql? до obj:

cycle {|element| ... } → nil Показать исходный код
cycle(count) {|element| ... } → nil
cycle → new_enumerator
cycle(count) → new_enumerator
static VALUE
rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
{
    long n, i;

    rb_check_arity(argc, 0, 1);

    RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
    if (argc == 0 || NIL_P(argv[0])) {
        n = -1;
    }
    else {
        n = NUM2LONG(argv[0]);
        if (n <= 0) return Qnil;
    }

    while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
        for (i=0; i<RARRAY_LEN(ary); i++) {
            rb_yield(RARRAY_AREF(ary, i));
        }
    }
    return Qnil;
}

При вызове с положительным целочисленным аргументом count и блоком, вызывает блок с каждым элементом, затем делает это снова, пока не вызовет count раз; возвращает nil:

output = []
[0, 1].cycle(2) {|element| output.push(element) } # => nil
output # => [0, 1, 0, 1]

Если count равно нулю или отрицательно, блок не вызывается:

[0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil
[0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil

Если задан блок, а аргумент опущен или nil, цикл продолжается бесконечно:

# Prints 0 and 1 forever.
[0, 1].cycle {|element| puts element }
[0, 1].cycle(nil) {|element| puts element }

Если блок не задан, возвращает новый перечислитель:

[0, 1].cycle(2) # => #<Enumerator: [0, 1]:cycle(2)>
[0, 1].cycle # => # => #<Enumerator: [0, 1]:cycle>
[0, 1].cycle.first(5) # => [0, 1, 0, 1, 0]
deconstruct() Показать исходный код
static VALUE
rb_ary_deconstruct(VALUE ary)
{
    return ary;
}
delete(obj) → deleted_object Показать исходный код
delete(obj) {|nosuch| ... } → deleted_object or block_return
VALUE
rb_ary_delete(VALUE ary, VALUE item)
{
    VALUE v = item;
    long i1, i2;

    for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
        VALUE e = RARRAY_AREF(ary, i1);

        if (rb_equal(e, item)) {
            v = e;
            continue;
        }
        if (i1 != i2) {
            rb_ary_store(ary, i2, e);
        }
        i2++;
    }
    if (RARRAY_LEN(ary) == i2) {
        if (rb_block_given_p()) {
            return rb_yield(item);
        }
        return Qnil;
    }

    ary_resize_smaller(ary, i2);

    ary_verify(ary);
    return v;
}

Удаляет один или несколько элементов из self; возвращает self.

Когда блок не задан, удаляет из self каждый элемент ele, такой что ele == obj; возвращает последний удалённый элемент:

s1 = 'bar'; s2 = 'bar'
a = [:foo, s1, 2, s2]
a.delete('bar') # => "bar"
a # => [:foo, 2]

Возвращает nil, если элементы не удалены.

Когда блок задан, удаляет из self каждый элемент ele, такой что ele == obj.

Если такие элементы найдены, игнорирует блок и возвращает последний удалённый элемент:

s1 = 'bar'; s2 = 'bar'
a = [:foo, s1, 2, s2]
deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' }
a # => [:foo, 2]

Если такие элементы не найдены, возвращает значение, возвращаемое блоком:

a = [:foo, 'bar', 2]
a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found"
delete_at(index) → deleted_object or nil Показать исходный код
static VALUE
rb_ary_delete_at_m(VALUE ary, VALUE pos)
{
    return rb_ary_delete_at(ary, NUM2LONG(pos));
}

Удаляет элемент из self, согласно заданному целому числу index.

Когда index неотрицательное, удаляет элемент с смещением index:

a = [:foo, 'bar', 2]
a.delete_at(1) # => "bar"
a # => [:foo, 2]

Если индекс слишком большой, возвращает nil.

Когда index отрицательное, отсчитывает назад от конца массива:

a = [:foo, 'bar', 2]
a.delete_at(-2) # => "bar"
a # => [:foo, 2]

Если index слишком мало (далеко от нуля), возвращает nil.

delete_if {|element| ... } → self Показать исходный код
delete_if → Enumerator
static VALUE
rb_ary_delete_if(VALUE ary)
{
    ary_verify(ary);
    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    ary_reject_bang(ary);
    return ary;
}

Удаляет каждый элемент в self, для которого блок возвращает истинное значение; возвращает self:

a = [:foo, 'bar', 2, 'bat']
a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if>
difference(*other_arrays) → new_array Показать исходный код
static VALUE
rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
{
    VALUE ary_diff;
    long i, length;
    volatile VALUE t0;
    bool *is_hash = ALLOCV_N(bool, t0, argc);
    ary_diff = rb_ary_new();
    length = RARRAY_LEN(ary);

    for (i = 0; i < argc; i++) {
        argv[i] = to_ary(argv[i]);
        is_hash[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
        if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        int j;
        VALUE elt = rb_ary_elt(ary, i);
        for (j = 0; j < argc; j++) {
            if (is_hash[j]) {
                if (rb_hash_stlike_lookup(argv[j], RARRAY_AREF(ary, i), NULL))
                    break;
            }
            else {
                if (rb_ary_includes_by_eql(argv[j], elt)) break;
            }
        }
        if (j == argc) rb_ary_push(ary_diff, elt);
    }

    ALLOCV_END(t0);

    return ary_diff;
}

Возвращает новый массив, содержащий только те элементы из self, которые не найдены ни в одном из массивов other_arrays; элементы сравниваются с помощью eql?; порядок из self сохраняется:

[0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3]
[0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2]
[0, 1, 2].difference([4]) # => [0, 1, 2]

Возвращает копию self, если аргументы не заданы.

Связанный метод: Array#-.

dig(index, *identifiers) → object Показать исходный код
static VALUE
rb_ary_dig(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    self = rb_ary_at(self, *argv);
    if (!--argc) return self;
    ++argv;
    return rb_obj_dig(argc, argv, self, Qnil);
}

Находит и возвращает объект во вложенных объектах, который указан index и identifiers. Вложенные объекты могут быть экземплярами различных классов. См. Методы Dig.

Примеры:

a = [:foo, [:bar, :baz, [:bat, :bam]]]
a.dig(1) # => [:bar, :baz, [:bat, :bam]]
a.dig(1, 2) # => [:bat, :bam]
a.dig(1, 2, 0) # => :bat
a.dig(1, 2, 3) # => nil
drop(n) → new_array Показать исходный код
static VALUE
rb_ary_drop(VALUE ary, VALUE n)
{
    VALUE result;
    long pos = NUM2LONG(n);
    if (pos < 0) {
        rb_raise(rb_eArgError, "attempt to drop negative size");
    }

    result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
    if (result == Qnil) result = rb_ary_new();
    return result;
}

Возвращает новый массив, содержащий все, кроме первых n элементов self, где n - неотрицательное целое число; не изменяет self.

Примеры:

a = [0, 1, 2, 3, 4, 5]
a.drop(0) # => [0, 1, 2, 3, 4, 5]
a.drop(1) # => [1, 2, 3, 4, 5]
a.drop(2) # => [2, 3, 4, 5]
drop_while {|element| ... } → new_array Показать исходный код
drop_while → new_enumerator
static VALUE
rb_ary_drop_while(VALUE ary)
{
    long i;

    RETURN_ENUMERATOR(ary, 0, 0);
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
    }
    return rb_ary_drop(ary, LONG2FIX(i));
}

Возвращает новый массив, содержащий нуль или более конечных элементов self; не изменяет self.

Если задан блок, вызывает блок с каждым последующим элементом self; останавливается, если блок возвращает false или nil; возвращает новый Array без тех элементов, для которых блок возвратил истинное значение:

a = [0, 1, 2, 3, 4, 5]
a.drop_while {|element| element < 3 } # => [3, 4, 5]

Без блока возвращает новый перечислитель:

[0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while>
each {|element| ... } → self Показать исходный код
each → Enumerator
VALUE
rb_ary_each(VALUE ary)
{
    long i;
    ary_verify(ary);
    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    for (i=0; i<RARRAY_LEN(ary); i++) {
        rb_yield(RARRAY_AREF(ary, i));
    }
    return ary;
}

Итерирует по элементам массива.

Если задан блок, передаёт каждый последующий элемент массива в блок; возвращает self:

a = [:foo, 'bar', 2]
a.each {|element|  puts "#{element.class} #{element}" }

Вывод:

Symbol foo
String bar
Integer 2

Позволяет изменять массив во время итерации:

a = [:foo, 'bar', 2]
a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }

Вывод:

foo
bar

Если блок не задан, возвращает новый перечислитель:

a = [:foo, 'bar', 2]
e = a.each
e # => #<Enumerator: [:foo, "bar", 2]:each>
a1 = e.each {|element|  puts "#{element.class} #{element}" }

Вывод:

Symbol foo
String bar
Integer 2

Связанные методы: each_index, reverse_each.

each_index {|index| ... } → self Показать исходный код
each_index → Enumerator
static VALUE
rb_ary_each_index(VALUE ary)
{
    long i;
    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);

    for (i=0; i<RARRAY_LEN(ary); i++) {
        rb_yield(LONG2NUM(i));
    }
    return ary;
}

Итерирует по индексам массива.

Если задан блок, передаёт каждый последующий индекс массива в блок; возвращает self:

a = [:foo, 'bar', 2]
a.each_index {|index|  puts "#{index} #{a[index]}" }

Вывод:

0 foo
1 bar
2 2

Позволяет изменять массив во время итерации:

a = [:foo, 'bar', 2]
a.each_index {|index| puts index; a.clear if index > 0 }

Вывод:

0
1

Если блок не задан, возвращает новый перечислитель:

a = [:foo, 'bar', 2]
e = a.each_index
e # => #<Enumerator: [:foo, "bar", 2]:each_index>
a1 = e.each {|index|  puts "#{index} #{a[index]}"}

Вывод:

0 foo
1 bar
2 2

Связанные методы: each, reverse_each.

empty? → true or false Показать исходный код
static VALUE
rb_ary_empty_p(VALUE ary)
{
    if (RARRAY_LEN(ary) == 0)
        return Qtrue;
    return Qfalse;
}

Возвращает true, если количество элементов в self равно нулю, false в противном случае.

eql? other_array → true or false Показать исходный код
static VALUE
rb_ary_eql(VALUE ary1, VALUE ary2)
{
    if (ary1 == ary2) return Qtrue;
    if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
    if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
    if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
    return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
}

Возвращает true, если self и other_array имеют одинаковый размер, и если для каждого индекса i в self, self[i].eql? other_array[i]:

a0 = [:foo, 'bar', 2]
a1 = [:foo, 'bar', 2]
a1.eql?(a0) # => true

В противном случае возвращает false.

Этот метод отличается от метода Array#==, который сравнивает с помощью метода Object#==.

fetch(index) → element Показать исходный код
fetch(index, default_value) → element
fetch(index) {|index| ... } → element
static VALUE
rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
{
    VALUE pos, ifnone;
    long block_given;
    long idx;

    rb_scan_args(argc, argv, "11", &pos, &ifnone);
    block_given = rb_block_given_p();
    if (block_given && argc == 2) {
        rb_warn("block supersedes default value argument");
    }
    idx = NUM2LONG(pos);

    if (idx < 0) {
        idx +=  RARRAY_LEN(ary);
    }
    if (idx < 0 || RARRAY_LEN(ary) <= idx) {
        if (block_given) return rb_yield(pos);
        if (argc == 1) {
            rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
                        idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
        }
        return ifnone;
    }
    return RARRAY_AREF(ary, idx);
}

Возвращает элемент со смещением index.

С единственным аргументом целого числа index, возвращает элемент со смещением index:

a = [:foo, 'bar', 2]
a.fetch(1) # => "bar"

Если index отрицательное, отсчитывает с конца массива:

a = [:foo, 'bar', 2]
a.fetch(-1) # => 2
a.fetch(-2) # => "bar"

С аргументами index и default_value, возвращает элемент со смещением index, если индекс находится в диапазоне, в противном случае возвращает default_value:

a = [:foo, 'bar', 2]
a.fetch(1, nil) # => "bar"

С аргументом index и блоком, возвращает элемент со смещением index, если индекс находится в диапазоне (и блок не вызывается); в противном случае вызывает блок с индексом и возвращает его возвращаемое значение:

a = [:foo, 'bar', 2]
a.fetch(1) {|index| raise 'Cannot happen' } # => "bar"
a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50"
fill(obj) → self Показать исходный код
fill(obj, start) → self
fill(obj, start, length) → self
fill(obj, range) → self
fill {|index| ... } → self
fill(start) {|index| ... } → self
fill(start, length) {|index| ... } → self
fill(range) {|index| ... } → self
static VALUE
rb_ary_fill(int argc, VALUE *argv, VALUE ary)
{
    VALUE item = Qundef, arg1, arg2;
    long beg = 0, end = 0, len = 0;

    if (rb_block_given_p()) {
        rb_scan_args(argc, argv, "02", &arg1, &arg2);
        argc += 1;             /* hackish */
    }
    else {
        rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
    }
    switch (argc) {
      case 1:
        beg = 0;
        len = RARRAY_LEN(ary);
        break;
      case 2:
        if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
            break;
        }
        /* fall through */
      case 3:
        beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
        if (beg < 0) {
            beg = RARRAY_LEN(ary) + beg;
            if (beg < 0) beg = 0;
        }
        len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
        break;
    }
    rb_ary_modify(ary);
    if (len < 0) {
        return ary;
    }
    if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
        rb_raise(rb_eArgError, "argument too big");
    }
    end = beg + len;
    if (RARRAY_LEN(ary) < end) {
        if (end >= ARY_CAPA(ary)) {
            ary_resize_capa(ary, end);
        }
        ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
        ARY_SET_LEN(ary, end);
    }

    if (item == Qundef) {
        VALUE v;
        long i;

        for (i=beg; i<end; i++) {
            v = rb_yield(LONG2NUM(i));
            if (i>=RARRAY_LEN(ary)) break;
            ARY_SET(ary, i, v);
        }
    }
    else {
        ary_memfill(ary, beg, len, item);
    }
    return ary;
}

Заменяет указанные элементы в self на указанные объекты; возвращает self.

С аргументом obj и без блока, заменяет все элементы одним объектом:

a = ['a', 'b', 'c', 'd']
a # => ["a", "b", "c", "d"]
a.fill(:X) # => [:X, :X, :X, :X]

С аргументами obj и целым числом start, и без блока, заменяет элементы, начиная с указанного стартового индекса.

Если start находится в диапазоне (0 <= start < array.size), заменяет все элементы с смещения start до конца:

a = ['a', 'b', 'c', 'd']
a.fill(:X, 2) # => ["a", "b", :X, :X]

Если start слишком велико (start >= array.size), ничего не делает:

a = ['a', 'b', 'c', 'd']
a.fill(:X, 4) # => ["a", "b", "c", "d"]
a = ['a', 'b', 'c', 'd']
a.fill(:X, 5) # => ["a", "b", "c", "d"]

Если start отрицательно, считает с конца (индекс начала — start + array.size):

a = ['a', 'b', 'c', 'd']
a.fill(:X, -2) # => ["a", "b", :X, :X]

Если start слишком мало (меньше и очень далеко от нуля), заменяет все элементы:

a = ['a', 'b', 'c', 'd']
a.fill(:X, -6) # => [:X, :X, :X, :X]
a = ['a', 'b', 'c', 'd']
a.fill(:X, -50) # => [:X, :X, :X, :X]

С аргументами obj, целым числом start, и целым числом length, и без блока, заменяет элементы, исходя из заданного start и length.

Если start находится в диапазоне, заменяет length элементов, начиная со смещения start:

a = ['a', 'b', 'c', 'd']
a.fill(:X, 1, 1) # => ["a", :X, "c", "d"]

Если start отрицательно, считает с конца:

a = ['a', 'b', 'c', 'd']
a.fill(:X, -2, 1) # => ["a", "b", :X, "d"]

Если start велико (start >= array.size), расширяет self на nil:

a = ['a', 'b', 'c', 'd']
a.fill(:X, 5, 0) # => ["a", "b", "c", "d", nil]
a = ['a', 'b', 'c', 'd']
a.fill(:X, 5, 2) # => ["a", "b", "c", "d", nil, :X, :X]

Если length равно нулю или отрицательно, не заменяет никаких элементов:

a = ['a', 'b', 'c', 'd']
a.fill(:X, 1, 0) # => ["a", "b", "c", "d"]
a.fill(:X, 1, -1) # => ["a", "b", "c", "d"]

С аргументами obj и диапазоном range, и без блока, заменяет элементы, исходя из заданного диапазона.

Если диапазон положительный и возрастающий (0 < range.begin <= range.end), заменяет элементы с range.begin по range.end:

a = ['a', 'b', 'c', 'd']
a.fill(:X, (1..1)) # => ["a", :X, "c", "d"]

Если range.first отрицательно, не заменяет никаких элементов:

a = ['a', 'b', 'c', 'd']
a.fill(:X, (-1..1)) # => ["a", "b", "c", "d"]

Если range.last отрицательно, считает с конца:

a = ['a', 'b', 'c', 'd']
a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"]
a = ['a', 'b', 'c', 'd']
a.fill(:X, (1..-2)) # => ["a", :X, :X, "d"]

Если range.last и range.last оба отрицательны, оба считаются с конца массива:

a = ['a', 'b', 'c', 'd']
a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X]
a = ['a', 'b', 'c', 'd']
a.fill(:X, (-2..-2)) # => ["a", "b", :X, "d"]

Без аргументов и с блоком, вызывает блок с каждым индексом; заменяет соответствующий элемент возвращаемым значением блока:

a = ['a', 'b', 'c', 'd']
a.fill { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]

С аргументом start и блоком, вызывает блок с каждым индексом от смещения start до конца; заменяет соответствующий элемент возвращаемым значением блока:

Если start находится в диапазоне (0 <= start < array.size), заменяет элементы со смещения start до конца:

a = ['a', 'b', 'c', 'd']
a.fill(1) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "new_3"]

Если start слишком велико (start >= array.size), ничего не делает:

a = ['a', 'b', 'c', 'd']
a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
a = ['a', 'b', 'c', 'd']
a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]

Если start отрицательно, считает с конца:

a = ['a', 'b', 'c', 'd']
a.fill(-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "new_3"]

Если start слишком мало (start <= -array.size), заменяет все элементы:

a = ['a', 'b', 'c', 'd']
a.fill(-6) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
a = ['a', 'b', 'c', 'd']
a.fill(-50) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]

С аргументами start и length, и блоком, вызывает блок для каждого индекса, заданного start length; заменяет соответствующий элемент возвращаемым значением блока.

Если start находится в диапазоне, заменяет length элементов, начиная со смещения start:

a = ['a', 'b', 'c', 'd']
a.fill(1, 1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]

Если start отрицательный, считает с конца:

a = ['a', 'b', 'c', 'd']
a.fill(-2, 1) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]

Если start велико (start >= array.size), расширяет self на nil:

a = ['a', 'b', 'c', 'd']
a.fill(5, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil]
a = ['a', 'b', 'c', 'd']
a.fill(5, 2) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil, "new_5", "new_6"]

Если length равно нулю или меньше, не заменяет никаких элементов:

a = ['a', 'b', 'c', 'd']
a.fill(1, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
a.fill(1, -1) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]

С аргументами obj и range, и блоком, вызывает блок с каждым индексом в заданном диапазоне; заменяет соответствующий элемент возвращаемым значением блока.

Если диапазон положительный и возрастающий (range 0 < range.begin <= range.end), заменяет элементы с range.begin по range.end:

a = ['a', 'b', 'c', 'd']
a.fill(1..1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]

Если range.first отрицательно, ничего не делает:

a = ['a', 'b', 'c', 'd']
a.fill(-1..1) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]

Если range.last отрицательно, считает с конца:

a = ['a', 'b', 'c', 'd']
a.fill(0..-2) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "d"]
a = ['a', 'b', 'c', 'd']
a.fill(1..-2) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "d"]

Если range.first и range.last оба отрицательны, оба считают с конца:

a = ['a', 'b', 'c', 'd']
a.fill(-1..-1) { |index| "new_#{index}" } # => ["a", "b", "c", "new_3"]
a = ['a', 'b', 'c', 'd']
a.fill(-2..-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]

Вызывает блок, если он задан, с каждым элементом массива self; возвращает новый массив, содержащий те элементы self, для которых блок возвращает истинное значение:

a = [:foo, 'bar', 2, :bam]
a1 = a.select {|element| element.to_s.start_with?('b') }
a1 # => ["bar", :bam]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2, :bam]
a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>

Array#filter — псевдоним для Array#select.

Также известен как: map!
Псевдоним для: select

Вызывает блок, если он задан, с каждым элементом self; удаляет из self те элементы, для которых блок возвращает false или nil.

Возвращает self если были удалены какие-либо элементы:

a = [:foo, 'bar', 2, :bam]
a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]

Возвращает nil если не было удалено ни одного элемента.

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2, :bam]
a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>

Array#filter! — псевдоним для Array#select!.

Псевдоним для: select!
static VALUE
rb_ary_index(int argc, VALUE *argv, VALUE ary)
{
    VALUE val;
    long i;

    if (argc == 0) {
        RETURN_ENUMERATOR(ary, 0, 0);
        for (i=0; i<RARRAY_LEN(ary); i++) {
            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
                return LONG2NUM(i);
            }
        }
        return Qnil;
    }
    rb_check_arity(argc, 0, 1);
    val = argv[0];
    if (rb_block_given_p())
        rb_warn("given block not used");
    for (i=0; i<RARRAY_LEN(ary); i++) {
        VALUE e = RARRAY_AREF(ary, i);
        if (rb_equal(e, val)) {
            return LONG2NUM(i);
        }
    }
    return Qnil;
}

Возвращает индекс указанного элемента.

Когда задан аргумент object, но нет блока, возвращает индекс первого элемента element, для которого object == element:

a = [:foo, 'bar', 2, 'bar']
a.index('bar') # => 1

Возвращает nil если такой элемент не найден.

Когда заданы и аргумент object, и блок, вызывает блок с каждым последующим элементом; возвращает индекс первого элемента, для которого блок возвращает истинное значение:

a = [:foo, 'bar', 2, 'bar']
a.index {|element| element == 'bar' } # => 1

Возвращает nil если блок никогда не возвращает истинное значение.

Когда ни аргумент, ни блок не заданы, возвращает новый перечислитель:

a = [:foo, 'bar', 2]
e = a.index
e # => #<Enumerator: [:foo, "bar", 2]:index>
e.each {|element| element == 'bar' } # => 1

Array#find_index — псевдоним для Array#index.

Связанное: rindex.

Также известен как: index
first → object or nil Показать исходный код
first(n) → new_array
static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
    if (argc == 0) {
        if (RARRAY_LEN(ary) == 0) return Qnil;
        return RARRAY_AREF(ary, 0);
    }
    else {
        return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
    }
}

Возвращает элементы из self; не изменяет self.

Без аргумента возвращает первый элемент:

a = [:foo, 'bar', 2]
a.first # => :foo
a # => [:foo, "bar", 2]

Если self пусто, возвращает nil.

Когда задан положительный целочисленный аргумент n, возвращает первые n элементов в новом массиве:

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

Если n >= array.size, возвращает все элементы:

a = [:foo, 'bar', 2]
a.first(50) # => [:foo, "bar", 2]

Если n == 0 возвращает новый пустой массив:

a = [:foo, 'bar', 2]
a.first(0) # []

Связанное: last.

flatten → new_array Показать исходный код
flatten(level) → new_array
static VALUE
rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
{
    int level = -1;
    VALUE result;

    if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
        level = NUM2INT(argv[0]);
        if (level == 0) return ary_make_shared_copy(ary);
    }

    result = flatten(ary, level);
    if (result == ary) {
        result = ary_make_shared_copy(ary);
    }

    return result;
}

Возвращает новый массив, который является рекурсивным разглаживанием self:

  • Каждый элемент, не являющийся массивом, остается неизменным.

  • Каждый массив заменяется своими отдельными элементами.

С положительным целочисленным аргументом level, рекурсивно разглаживает до level уровней:

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

Без аргумента, с аргументом nil, или с отрицательным аргументом level, разглаживает все уровни:

a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten # => [0, 1, 2]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(-1) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(-2) # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten(-1) # => [0, 1, 2]
flatten! → self or nil Показать исходный код
flatten!(level) → self or nil
static VALUE
rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
{
    int mod = 0, level = -1;
    VALUE result, lv;

    lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);
    rb_ary_modify_check(ary);
    if (!NIL_P(lv)) level = NUM2INT(lv);
    if (level == 0) return Qnil;

    result = flatten(ary, level);
    if (result == ary) {
        return Qnil;
    }
    if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
    rb_ary_replace(ary, result);
    if (mod) ARY_SET_EMBED_LEN(result, 0);

    return ary;
}

Заменяет каждый вложенный массив в self элементами из этого массива; возвращает self если изменения произошли, nil в противном случае.

С положительным целочисленным аргументом level, рекурсивно разглаживает до level уровней:

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

Без аргумента, с аргументом nil, или с отрицательным аргументом level, разглаживает все уровни:

a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten! # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten! # => nil
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(-1) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(-2) # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten!(-1) # => nil
END_OF_DOCUMENT_MARKER
hash → integer Show source
static VALUE
rb_ary_hash(VALUE ary)
{
    long i;
    st_index_t h;
    VALUE n;

    h = rb_hash_start(RARRAY_LEN(ary));
    h = rb_hash_uint(h, (st_index_t)rb_ary_hash);
    for (i=0; i<RARRAY_LEN(ary); i++) {
        n = rb_hash(RARRAY_AREF(ary, i));
        h = rb_hash_uint(h, NUM2LONG(n));
    }
    h = rb_hash_end(h);
    return ST2FIX(h);
}

Возвращает целочисленное значение хэш-кода для self.

Два массива с одинаковым содержимым будут иметь одинаковый хэш-код (и будут сравниваться с использованием eql?):

[0, 1, 2].hash == [0, 1, 2].hash # => true
[0, 1, 2].hash == [0, 1, 3].hash # => false
include?(obj) → true or false Show source
VALUE
rb_ary_includes(VALUE ary, VALUE item)
{
    long i;
    VALUE e;

    for (i=0; i<RARRAY_LEN(ary); i++) {
        e = RARRAY_AREF(ary, i);
        if (rb_equal(e, item)) {
            return Qtrue;
        }
    }
    return Qfalse;
}

Возвращает true если для некоторого индекса i в self, obj == self[i]; в противном случае false:

[0, 1, 2].include?(2) # => true
[0, 1, 2].include?(3) # => false
index(object) → integer or nil
index {|element| ... } → integer or nil
index → new_enumerator

Возвращает индекс указанного элемента.

Когда аргумент object задан, но блока нет, возвращает индекс первого элемента element, для которого object == element:

a = [:foo, 'bar', 2, 'bar']
a.index('bar') # => 1

Возвращает nil, если такой элемент не найден.

Когда заданы как аргумент object, так и блок, вызывает блок с каждым последующим элементом; возвращает индекс первого элемента, для которого блок возвращает истинное значение:

a = [:foo, 'bar', 2, 'bar']
a.index {|element| element == 'bar' } # => 1

Возвращает nil, если блок никогда не возвращает истинное значение.

Когда не задан ни аргумент, ни блок, возвращает новый перечислитель:

a = [:foo, 'bar', 2]
e = a.index
e # => #<Enumerator: [:foo, "bar", 2]:index>
e.each {|element| element == 'bar' } # => 1

Array#find_index является псевдонимом для Array#index.

Связанное: rindex.

Псевдоним для: find_index
VALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
    rb_ary_modify_check(copy);
    orig = to_ary(orig);
    if (copy == orig) return copy;

    if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
        VALUE shared_root = 0;

        if (ARY_OWNS_HEAP_P(copy)) {
            ary_heap_free(copy);
        }
        else if (ARY_SHARED_P(copy)) {
            shared_root = ARY_SHARED_ROOT(copy);
            FL_UNSET_SHARED(copy);
        }
        FL_SET_EMBED(copy);
        ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
        if (shared_root) {
            rb_ary_decrement_share(shared_root);
        }
        ARY_SET_LEN(copy, RARRAY_LEN(orig));
    }
    else {
        VALUE shared_root = ary_make_shared(orig);
        if (ARY_OWNS_HEAP_P(copy)) {
            ary_heap_free(copy);
        }
        else {
            rb_ary_unshare_safe(copy);
        }
        FL_UNSET_EMBED(copy);
        ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
        ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
        rb_ary_set_shared(copy, shared_root);
    }
    ary_verify(copy);
    return copy;
}

Заменяет содержимое self содержимым other_array; возвращает self:

a = [:foo, 'bar', 2]
a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
Также является псевдонимом для: replace
insert(index, *objects) → self Show source
static VALUE
rb_ary_insert(int argc, VALUE *argv, VALUE ary)
{
    long pos;

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    rb_ary_modify_check(ary);
    pos = NUM2LONG(argv[0]);
    if (argc == 1) return ary;
    if (pos == -1) {
        pos = RARRAY_LEN(ary);
    }
    else if (pos < 0) {
        long minpos = -RARRAY_LEN(ary) - 1;
        if (pos < minpos) {
            rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
                     pos, minpos);
        }
        pos++;
    }
    rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
    return ary;
}

Вставляет заданные objects до или после элемента с целочисленным индексом offset; возвращает self.

Когда index неотрицательно, вставляет все заданные objects перед элементом со смещением index:

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

Расширяет массив, если index выходит за пределы массива (index >= self.size):

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

Ничего не делает, если объекты не заданы:

a = [:foo, 'bar', 2]
a.insert(1)
a.insert(50)
a.insert(-50)
a # => [:foo, "bar", 2]

Когда index отрицательно, вставляет все заданные objects после элемента со смещением index+self.size:

a = [:foo, 'bar', 2]
a.insert(-2, :bat, :bam)
a # => [:foo, "bar", :bat, :bam, 2]
inspect → new_string Show source
static VALUE
rb_ary_inspect(VALUE ary)
{
    if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
    return rb_exec_recursive(inspect_ary, ary, 0);
}

Возвращает новую строку, образованную вызовом метода #inspect для каждого элемента массива:

a = [:foo, 'bar', 2]
a.inspect # => "[:foo, \"bar\", 2]"

Array#to_s является псевдонимом для Array#inspect.

Также является псевдонимом для: to_s
intersection(*other_arrays) → new_array Show source
static VALUE
rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
{
    VALUE result = rb_ary_dup(ary);
    int i;

    for (i = 0; i < argc; i++) {
        result = rb_ary_and(result, argv[i]);
    }

    return result;
}

Возвращает новый массив, содержащий каждый элемент, найденный как в self, так и во всех заданных массивах other_arrays; дубликаты опущены; элементы сравниваются с использованием eql?:

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

Сохраняет порядок из self:

[0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]

Возвращает копию self, если аргументы не заданы.

Связанное: Array#&.

join →new_string Show source
join(separator = $,) → new_string
static VALUE
rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
{
    VALUE sep;

    if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
        sep = rb_output_fs;
        if (!NIL_P(sep)) {
            rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
        }
    }

    return rb_ary_join(ary, sep);
}

Возвращает новую строку, образованную соединением элементов массива после преобразования. Для каждого элемента element

  • Использует element.to_s, если element не является kind_of?(Array).

  • Использует рекурсивное element.join(separator), если element является kind_of?(Array).

Без аргументов соединяет с использованием разделителя выходного поля, $,:

a = [:foo, 'bar', 2]
$, # => nil
a.join # => "foobar2"

Со строковым аргументом separator, соединяет с использованием этого разделителя:

a = [:foo, 'bar', 2]
a.join("\n") # => "foo\nbar\n2"

Соединяет рекурсивно для вложенных массивов:

a = [:foo, [:bar, [:baz, :bat]]]
a.join # => "foobarbazbat"
keep_if {|element| ... } → self Show source
keep_if → new_enumeration
static VALUE
rb_ary_keep_if(VALUE ary)
{
    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    rb_ary_select_bang(ary);
    return ary;
}

Сохраняет те элементы, для которых блок возвращает истинное значение; удаляет все остальные элементы; возвращает self:

a = [:foo, 'bar', 2, :bam]
a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2, :bam]
a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if>
last → object or nil Show source
last(n) → new_array
VALUE
rb_ary_last(int argc, const VALUE *argv, VALUE ary)
{
    if (argc == 0) {
        long len = RARRAY_LEN(ary);
        if (len == 0) return Qnil;
        return RARRAY_AREF(ary, len-1);
    }
    else {
        return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
    }
}

Возвращает элементы из self; self не изменяется.

Когда аргумент не задан, возвращает последний элемент:

a = [:foo, 'bar', 2]
a.last # => 2
a # => [:foo, "bar", 2]

Если self пуст, возвращает nil.

Когда задан неотрицательный целочисленный аргумент n, возвращает последние n элементов в новом массиве:

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

Если n >= array.size, возвращает все элементы:

a = [:foo, 'bar', 2]
a.last(50) # => [:foo, "bar", 2]

Если n == 0, возвращает новый пустой массив:

a = [:foo, 'bar', 2]
a.last(0) # []

Связанное: first.

length → an_integer Show source
static VALUE
rb_ary_length(VALUE ary)
{
    long len = RARRAY_LEN(ary);
    return LONG2NUM(len);
}

Возвращает количество элементов в self.

Также является псевдонимом для: size
map {|element| ... } → new_array
map → new_enumerator

Вызывает блок, если он задан, с каждым элементом self; возвращает новый массив, элементами которого являются возвращаемые значения из блока:

a = [:foo, 'bar', 2]
a1 = a.map {|element| element.class }
a1 # => [Symbol, String, Integer]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a1 = a.map
a1 # => #<Enumerator: [:foo, "bar", 2]:map>

Array#collect является псевдонимом для Array#map.

Псевдоним для: collect
map! {|element| ... } → self
map! → new_enumerator

Вызывает блок, если он задан, с каждым элементом; заменяет элемент возвращаемым значением блока:

a = [:foo, 'bar', 2]
a.map! { |element| element.class } # => [Symbol, String, Integer]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a1 = a.map!
a1 # => #<Enumerator: [:foo, "bar", 2]:map!>

Array#collect! является псевдонимом для Array#map!.

Псевдоним для: collect!
max → элемент Показать исходный код
max {|a, b| ... } → элемент
max(n) → новый_массив
max(n) {|a, b| ... } → новый_массив
static VALUE
rb_ary_max(int argc, VALUE *argv, VALUE ary)
{
    struct cmp_opt_data cmp_opt = { 0, 0 };
    VALUE result = Qundef, v;
    VALUE num;
    long i;

    if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
       return rb_nmin_run(ary, num, 0, 1, 1);

    const long n = RARRAY_LEN(ary);
    if (rb_block_given_p()) {
        for (i = 0; i < RARRAY_LEN(ary); i++) {
           v = RARRAY_AREF(ary, i);
           if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
               result = v;
           }
        }
    }
    else if (n > 0) {
        result = RARRAY_AREF(ary, 0);
        if (n > 1) {
            if (FIXNUM_P(result) && CMP_OPTIMIZABLE(cmp_opt, Integer)) {
                return ary_max_opt_fixnum(ary, 1, result);
            }
            else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
                return ary_max_opt_string(ary, 1, result);
            }
            else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
                return ary_max_opt_float(ary, 1, result);
            }
            else {
                return ary_max_generic(ary, 1, result);
            }
        }
    }
    if (result == Qundef) return Qnil;
    return result;
}

Возвращает одно из следующего:

  • Элемент с максимальным значением из self.

  • Новый массив элементов с максимальными значениями, выбранных из self.

Когда блок не задан, каждый элемент в self должен отвечать на метод <=> с целым числом.

Без аргумента и без блока, возвращает элемент в self с максимальным значением по методу <=>:

[0, 1, 2].max # => 2

С целым аргументом n и без блока, возвращает новый массив не более чем с n элементами в порядке убывания по методу <=>:

[0, 1, 2, 3].max(3) # => [3, 2, 1]
[0, 1, 2, 3].max(6) # => [3, 2, 1]

Когда задан блок, блок должен возвращать целое число.

С блоком и без аргумента, вызывает блок self.size-1 раз для сравнения элементов; возвращает элемент с максимальным значением по блоку:

['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000"

С аргументом n и блоком, возвращает новый массив не более чем с n элементами в порядке убывания по блоку:

['0', '00', '000'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"]
min → элемент Показать исходный код
min { |a, b| ... } → элемент
min(n) → новый_массив
min(n) { |a, b| ... } → новый_массив
static VALUE
rb_ary_min(int argc, VALUE *argv, VALUE ary)
{
    struct cmp_opt_data cmp_opt = { 0, 0 };
    VALUE result = Qundef, v;
    VALUE num;
    long i;

    if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
       return rb_nmin_run(ary, num, 0, 0, 1);

    const long n = RARRAY_LEN(ary);
    if (rb_block_given_p()) {
        for (i = 0; i < RARRAY_LEN(ary); i++) {
           v = RARRAY_AREF(ary, i);
           if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
               result = v;
           }
        }
    }
    else if (n > 0) {
        result = RARRAY_AREF(ary, 0);
        if (n > 1) {
            if (FIXNUM_P(result) && CMP_OPTIMIZABLE(cmp_opt, Integer)) {
                return ary_min_opt_fixnum(ary, 1, result);
            }
            else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
                return ary_min_opt_string(ary, 1, result);
            }
            else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
                return ary_min_opt_float(ary, 1, result);
            }
            else {
                return ary_min_generic(ary, 1, result);
            }
        }
    }
    if (result == Qundef) return Qnil;
    return result;
}

Возвращает одно из следующего:

  • Элемент с минимальным значением из self.

  • Новый массив элементов с минимальными значениями, выбранных из self.

Когда блок не задан, каждый элемент в self должен отвечать на метод <=> с целым числом.

Без аргумента и без блока, возвращает элемент в self с минимальным значением по методу <=>:

[0, 1, 2].min # => 0

С целым аргументом n и без блока, возвращает новый массив не более чем с n элементами в порядке возрастания по методу <=>:

[0, 1, 2, 3].min(3) # => [0, 1, 2]
[0, 1, 2, 3].min(6) # => [0, 1, 2, 3]

Когда задан блок, блок должен возвращать целое число.

С блоком и без аргумента, вызывает блок self.size-1 раз для сравнения элементов; возвращает элемент с минимальным значением по блоку:

['0', '00', '000'].min { |a, b| a.size <=> b.size } # => "0"

С аргументом n и блоком, возвращает новый массив не более чем с n элементами в порядке возрастания по блоку:

[0, 1, 2, 3].min(3) # => [0, 1, 2]
[0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
minmax → [min_val, max_val] Показать исходный код
minmax {|a, b| ... } → [min_val, max_val]
static VALUE
rb_ary_minmax(VALUE ary)
{
    if (rb_block_given_p()) {
        return rb_call_super(0, NULL);
    }
    return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
}

Возвращает новый массив из 2 элементов, содержащий минимальное и максимальное значения из self, либо по методу <=>, либо по заданному блоку:

Когда блок не задан, каждый элемент в self должен отвечать на метод <=> с целым числом; возвращает новый массив из 2 элементов, содержащий минимальное и максимальное значения из self, по методу <=>:

[0, 1, 2].minmax # => [0, 2]

Когда задан блок, блок должен возвращать целое число; блок вызывается self.size-1 раз для сравнения элементов; возвращает новый массив из 2 элементов, содержащий минимальное и максимальное значения из self, по блоку:

['0', '00', '000'].minmax {|a, b| a.size <=> b.size } # => ["0", "000"]
none? → true или false Показать исходный код
none? {|element| ... } → true или false
none?(obj) → true или false
static VALUE
rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
{
    long i, len = RARRAY_LEN(ary);

    rb_check_arity(argc, 0, 1);
    if (!len) return Qtrue;
    if (argc) {
        if (rb_block_given_p()) {
            rb_warn("given block not used");
        }
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
        }
    }
    else if (!rb_block_given_p()) {
        for (i = 0; i < len; ++i) {
            if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
        }
    }
    else {
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
        }
    }
    return Qtrue;
}

Возвращает true если ни один элемент из self не удовлетворяет заданному критерию.

Без блока и без аргумента, возвращает true если у self нет истинностных элементов, false в противном случае:

[nil, false].none? # => true
[nil, 0, false].none? # => false
[].none? # => true

С блоком и без аргумента, вызывает блок для каждого элемента в self; возвращает true если блок возвращает ни одно истинностное значение, false в противном случае:

[0, 1, 2].none? {|element| element > 3 } # => true
[0, 1, 2].none? {|element| element > 1 } # => false

Если аргумент obj задан, возвращает true если obj.=== ни одного элемента, false в противном случае:

['food', 'drink'].none?(/bar/) # => true
['food', 'drink'].none?(/foo/) # => false
[].none?(/foo/) # => true
[0, 1, 2].none?(3) # => true
[0, 1, 2].none?(1) # => false

Связанно с: Enumerable#none?

one? → true или false Показать исходный код
one? {|element| ... } → true или false
one?(obj) → true или false
static VALUE
rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
{
    long i, len = RARRAY_LEN(ary);
    VALUE result = Qfalse;

    rb_check_arity(argc, 0, 1);
    if (!len) return Qfalse;
    if (argc) {
        if (rb_block_given_p()) {
            rb_warn("given block not used");
        }
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
                if (result) return Qfalse;
                result = Qtrue;
            }
        }
    }
    else if (!rb_block_given_p()) {
        for (i = 0; i < len; ++i) {
            if (RTEST(RARRAY_AREF(ary, i))) {
                if (result) return Qfalse;
                result = Qtrue;
            }
        }
    }
    else {
        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
                if (result) return Qfalse;
                result = Qtrue;
            }
        }
    }
    return result;
}

Возвращает true если ровно один элемент из self удовлетворяет заданному критерию.

Без блока и без аргумента, возвращает true если self содержит ровно один истинный элемент, false в противном случае:

[nil, 0].one? # => true
[0, 0].one? # => false
[nil, nil].one? # => false
[].one? # => false

С блоком и без аргумента, вызывает блок для каждого элемента в self; возвращает true если блок возвращает истинностное значение ровно для одного элемента, false в противном случае:

[0, 1, 2].one? {|element| element > 0 } # => false
[0, 1, 2].one? {|element| element > 1 } # => true
[0, 1, 2].one? {|element| element > 2 } # => false

Если аргумент obj задан, возвращает true если obj.=== ровно один элемент, false в противном случае:

[0, 1, 2].one?(0) # => true
[0, 0, 1].one?(0) # => false
[1, 1, 2].one?(0) # => false
['food', 'drink'].one?(/bar/) # => false
['food', 'drink'].one?(/foo/) # => true
[].one?(/foo/) # => false

Связанно с: Enumerable#one?

pack( aTemplateString ) → aBinaryString Показать исходный код
pack( aTemplateString, buffer: aBufferString ) → aBufferString
# File pack.rb, line 133
def pack(fmt, buffer: nil)
  Primitive.pack_pack(fmt, buffer)
end

Упаковывает содержимое arr в двоичную последовательность в соответствии с инструкциями в aTemplateString (см. таблицу ниже). Директивы «A», «a» и «Z» могут быть дополнены счетчиком, который задает ширину результирующего поля. Остальные директивы также могут принимать счетчик, указывающий количество элементов массива для преобразования. Если счетчик является звездочкой («*»), все оставшиеся элементы массива будут преобразованы. Любые директивы «…», могут быть дополнены подчеркиванием («_») или восклицательным знаком («!»), чтобы использовать собственный размер платформы для указанного типа; в противном случае они используют платформенно-независимый размер. Пробелы игнорируются в строке шаблона. См. также String#unpack.

a = [ "a", "b", "c" ]
n = [ 65, 66, 67 ]
a.pack("A3A3A3")   #=> "a  b  c  "
a.pack("a3a3a3")   #=> "a\000\000b\000\000c\000\000"
n.pack("ccc")      #=> "ABC"

Если aBufferString указан и его емкости достаточно, pack использует его как буфер и возвращает его. Когда смещение задано началом aTemplateString, результат заполняется после смещения. Если исходное содержимое aBufferString существует и оно длиннее смещения, остальная часть offsetOfBuffer перезаписывается результатом. Если оно короче, пробел заполняется «\0».

Обратите внимание, что опция «buffer:» не гарантирует, что не будет выделена память в pack. Если емкости aBufferString недостаточно, pack выделяет память.

Директивы для pack.

Integer       | Array   |
Directive     | Element | Meaning
----------------------------------------------------------------------------
C             | Integer | 8-bit unsigned (unsigned char)
S             | Integer | 16-bit unsigned, native endian (uint16_t)
L             | Integer | 32-bit unsigned, native endian (uint32_t)
Q             | Integer | 64-bit unsigned, native endian (uint64_t)
J             | Integer | pointer width unsigned, native endian (uintptr_t)
              |         | (J is available since Ruby 2.3.)
              |         |
c             | Integer | 8-bit signed (signed char)
s             | Integer | 16-bit signed, native endian (int16_t)
l             | Integer | 32-bit signed, native endian (int32_t)
q             | Integer | 64-bit signed, native endian (int64_t)
j             | Integer | pointer width signed, native endian (intptr_t)
              |         | (j is available since Ruby 2.3.)
              |         |
S_ S!         | Integer | unsigned short, native endian
I I_ I!       | Integer | unsigned int, native endian
L_ L!         | Integer | unsigned long, native endian
Q_ Q!         | Integer | unsigned long long, native endian (ArgumentError
              |         | if the platform has no long long type.)
              |         | (Q_ and Q! is available since Ruby 2.1.)
J!            | Integer | uintptr_t, native endian (same with J)
              |         | (J! is available since Ruby 2.3.)
              |         |
s_ s!         | Integer | signed short, native endian
i i_ i!       | Integer | signed int, native endian
l_ l!         | Integer | signed long, native endian
q_ q!         | Integer | signed long long, native endian (ArgumentError
              |         | if the platform has no long long type.)
              |         | (q_ and q! is available since Ruby 2.1.)
j!            | Integer | intptr_t, native endian (same with j)
              |         | (j! is available since Ruby 2.3.)
              |         |
S> s> S!> s!> | Integer | same as the directives without ">" except
L> l> L!> l!> |         | big endian
I!> i!>       |         | (available since Ruby 1.9.3)
Q> q> Q!> q!> |         | "S>" is same as "n"
J> j> J!> j!> |         | "L>" is same as "N"
              |         |
S< s< S!< s!< | Integer | same as the directives without "<" except
L< l< L!< l!< |         | little endian
I!< i!<       |         | (available since Ruby 1.9.3)
Q< q< Q!< q!< |         | "S<" is same as "v"
J< j< J!< j!< |         | "L<" is same as "V"
              |         |
n             | Integer | 16-bit unsigned, network (big-endian) byte order
N             | Integer | 32-bit unsigned, network (big-endian) byte order
v             | Integer | 16-bit unsigned, VAX (little-endian) byte order
V             | Integer | 32-bit unsigned, VAX (little-endian) byte order
              |         |
U             | Integer | UTF-8 character
w             | Integer | BER-compressed integer

Float        | Array   |
Directive    | Element | Meaning
---------------------------------------------------------------------------
D d          | Float   | double-precision, native format
F f          | Float   | single-precision, native format
E            | Float   | double-precision, little-endian byte order
e            | Float   | single-precision, little-endian byte order
G            | Float   | double-precision, network (big-endian) byte order
g            | Float   | single-precision, network (big-endian) byte order

String       | Array   |
Directive    | Element | Meaning
---------------------------------------------------------------------------
A            | String  | arbitrary binary string (space padded, count is width)
a            | String  | arbitrary binary string (null padded, count is width)
Z            | String  | same as ``a'', except that null is added with *
B            | String  | bit string (MSB first)
b            | String  | bit string (LSB first)
H            | String  | hex string (high nibble first)
h            | String  | hex string (low nibble first)
u            | String  | UU-encoded string
M            | String  | quoted printable, MIME encoding (see also RFC2045)
             |         | (text mode but input must use LF and output LF)
m            | String  | base64 encoded string (see RFC 2045)
             |         | (if count is 0, no line feed are added, see RFC 4648)
             |         | (count specifies input bytes between each LF,
             |         | rounded down to nearest multiple of 3)
P            | String  | pointer to a structure (fixed-length string)
p            | String  | pointer to a null-terminated string

Misc.        | Array   |
Directive    | Element | Meaning
---------------------------------------------------------------------------
@            | ---     | moves to absolute position
X            | ---     | back up a byte
x            | ---     | null byte
permutation {|element| ... } → self Показать исходный код
permutation(n) {|element| ... } → self
permutation → new_enumerator
permutation(n) → new_enumerator
static VALUE
rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
{
    long r, n, i;

    n = RARRAY_LEN(ary);                  /* Array length */
    RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size);   /* Return enumerator if no block */
    r = n;
    if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
        r = NUM2LONG(argv[0]);            /* Permutation size from argument */

    if (r < 0 || n < r) {
        /* no permutations: yield nothing */
    }
    else if (r == 0) { /* exactly one permutation: the zero-length array */
        rb_yield(rb_ary_new2(0));
    }
    else if (r == 1) { /* this is a special, easy case */
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
        }
    }
    else {             /* this is the general case */
        volatile VALUE t0;
        long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
        char *used = (char*)(p + r);
        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
        RBASIC_CLEAR_CLASS(ary0);

        MEMZERO(used, char, n); /* initialize array */

        permute0(n, r, p, used, ary0); /* compute and yield permutations */
        ALLOCV_END(t0);
        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
    }
    return ary;
}

При вызове с блоком генерирует все перестановки элементов self; возвращает self. Порядок перестановок неопределен.

Когда задан блок и целое число-аргумент n (0 < n <= self.size) в диапазоне, вызываются блок со всеми перестановками n-элементных кортежей из self.

Пример:

a = [0, 1, 2]
a.permutation(2) {|permutation| p permutation }

Вывод:

[0, 1]
[0, 2]
[1, 0]
[1, 2]
[2, 0]
[2, 1]

Другой пример:

a = [0, 1, 2]
a.permutation(3) {|permutation| p permutation }

Вывод:

[0, 1, 2]
[0, 2, 1]
[1, 0, 2]
[1, 2, 0]
[2, 0, 1]
[2, 1, 0]

Когда n равно нулю, вызывает блок один раз с новым пустым массивом:

a = [0, 1, 2]
a.permutation(0) {|permutation| p permutation }

Вывод:

[]

Когда n выходит за пределы диапазона (отрицательно или больше, чем self.size ), не вызывается блок:

a = [0, 1, 2]
a.permutation(-1) {|permutation| fail 'Cannot happen' }
a.permutation(4) {|permutation| fail 'Cannot happen' }

Когда блок задан, но без аргумента, действует так же, как a.permutation(a.size):

a = [0, 1, 2]
a.permutation {|permutation| p permutation }

Вывод:

[0, 1, 2]
[0, 2, 1]
[1, 0, 2]
[1, 2, 0]
[2, 0, 1]
[2, 1, 0]

Возвращает новый перечислитель, если блок не задан:

a = [0, 1, 2]
a.permutation # => #<Enumerator: [0, 1, 2]:permutation>
a.permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
pop → object or nil Show source
pop(n) → new_array
static VALUE
rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
{
    VALUE result;

    if (argc == 0) {
        return rb_ary_pop(ary);
    }

    rb_ary_modify_check(ary);
    result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
    ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
    ary_verify(ary);
    return result;
}

Удаляет и возвращает конечные элементы.

Когда аргумент не задан и self не пуст, удаляет и возвращает последний элемент:

a = [:foo, 'bar', 2]
a.pop # => 2
a # => [:foo, "bar"]

Возвращает nil если массив пуст.

Когда задан неотрицательный целочисленный аргумент n и находится в диапазоне, удаляет и возвращает последние n элементов в новом массиве:

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

Если n положителен и находится вне диапазона, удаляет и возвращает все элементы:

a = [:foo, 'bar', 2]
a.pop(50) # => [:foo, "bar", 2]

Связанные: push, shift, unshift.

Добавляет заданный objects в начало self:

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

Array#prepend является псевдонимом для Array#unshift.

Связанные: push, pop, shift.

Псевдоним для: unshift
product(*other_arrays) → new_array Show source
product(*other_arrays) {|combination| ... } → self
static VALUE
rb_ary_product(int argc, VALUE *argv, VALUE ary)
{
    int n = argc+1;    /* How many arrays we're operating on */
    volatile VALUE t0 = tmpary(n);
    volatile VALUE t1 = Qundef;
    VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
    int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
    VALUE result = Qnil;      /* The array we'll be returning, when no block given */
    long i,j;
    long resultlen = 1;

    RBASIC_CLEAR_CLASS(t0);

    /* initialize the arrays of arrays */
    ARY_SET_LEN(t0, n);
    arrays[0] = ary;
    for (i = 1; i < n; i++) arrays[i] = Qnil;
    for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);

    /* initialize the counters for the arrays */
    for (i = 0; i < n; i++) counters[i] = 0;

    /* Otherwise, allocate and fill in an array of results */
    if (rb_block_given_p()) {
        /* Make defensive copies of arrays; exit if any is empty */
        for (i = 0; i < n; i++) {
            if (RARRAY_LEN(arrays[i]) == 0) goto done;
            arrays[i] = ary_make_shared_copy(arrays[i]);
        }
    }
    else {
        /* Compute the length of the result array; return [] if any is empty */
        for (i = 0; i < n; i++) {
            long k = RARRAY_LEN(arrays[i]);
            if (k == 0) {
                result = rb_ary_new2(0);
                goto done;
            }
            if (MUL_OVERFLOW_LONG_P(resultlen, k))
                rb_raise(rb_eRangeError, "too big to product");
            resultlen *= k;
        }
        result = rb_ary_new2(resultlen);
    }
    for (;;) {
        int m;
        /* fill in one subarray */
        VALUE subarray = rb_ary_new2(n);
        for (j = 0; j < n; j++) {
            rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
        }

        /* put it on the result array */
        if (NIL_P(result)) {
            FL_SET(t0, FL_USER5);
            rb_yield(subarray);
            if (! FL_TEST(t0, FL_USER5)) {
                rb_raise(rb_eRuntimeError, "product reentered");
            }
            else {
                FL_UNSET(t0, FL_USER5);
            }
        }
        else {
            rb_ary_push(result, subarray);
        }

        /*
         * Increment the last counter.  If it overflows, reset to 0
         * and increment the one before it.
         */
        m = n-1;
        counters[m]++;
        while (counters[m] == RARRAY_LEN(arrays[m])) {
            counters[m] = 0;
            /* If the first counter overflows, we are done */
            if (--m < 0) goto done;
            counters[m]++;
        }
    }
done:
    tmpary_discard(t0);
    ALLOCV_END(t1);

    return NIL_P(result) ? ary : result;
}

Вычисляет и возвращает или генерирует все комбинации элементов из всех массивов, включая как self, так и other_arrays.

  • Количество комбинаций равно произведению размеров всех массивов, включая как self, так и other_arrays.

  • Порядок возвращаемых комбинаций неопределен.

Когда блок не задан, возвращает комбинации в виде массива массивов:

a = [0, 1, 2]
a1 = [3, 4]
a2 = [5, 6]
p = a.product(a1)
p.size # => 6 # a.size * a1.size
p # => [[0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]]
p = a.product(a1, a2)
p.size # => 12 # a.size * a1.size * a2.size
p # => [[0, 3, 5], [0, 3, 6], [0, 4, 5], [0, 4, 6], [1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]

Если любой аргумент является пустым массивом, возвращает пустой массив.

Если аргумент не задан, возвращает массив из одноэлементных массивов, каждый из которых содержит элемент self:

a.product # => [[0], [1], [2]]

Когда задан блок, генерирует каждую комбинацию как массив; возвращает self:

a.product(a1) {|combination| p combination }

Вывод:

[0, 3]
[0, 4]
[1, 3]
[1, 4]
[2, 3]
[2, 4]

Если любой аргумент является пустым массивом, блок не вызывается:

a.product(a1, a2, []) {|combination| fail 'Cannot happen' }

Если аргумент не задан, генерирует каждый элемент self как одноэлементный массив:

a.product {|combination| p combination }

Вывод:

[0]
[1]
[2]
push(*objects) → self Show source
static VALUE
rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
{
    return rb_ary_cat(ary, argv, argc);
}

Добавляет конечные элементы.

Добавляет каждый аргумент в objects к self; возвращает self:

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

Добавляет каждый аргумент как один элемент, даже если это другой массив:

a = [:foo, 'bar', 2]
a1 = a.push([:baz, :bat], [:bam, :bad])
a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]

Array#append является псевдонимом для Array#push.

Связанные: pop, shift, unshift.

Также является псевдонимом для: append
rassoc(obj) → found_array or nil Show source
VALUE
rb_ary_rassoc(VALUE ary, VALUE value)
{
    long i;
    VALUE v;

    for (i = 0; i < RARRAY_LEN(ary); ++i) {
        v = RARRAY_AREF(ary, i);
        if (RB_TYPE_P(v, T_ARRAY) &&
            RARRAY_LEN(v) > 1 &&
            rb_equal(RARRAY_AREF(v, 1), value))
            return v;
    }
    return Qnil;
}

Возвращает первый элемент в self, который является массивом, второй элемент которого == obj:

a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
a.rassoc(4) # => [2, 4]

Возвращает nil, если такой элемент не найден.

Связанные: assoc.

reject {|element| ... } → new_array Show source
reject → new_enumerator
static VALUE
rb_ary_reject(VALUE ary)
{
    VALUE rejected_ary;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    rejected_ary = rb_ary_new();
    ary_reject(ary, rejected_ary);
    return rejected_ary;
}

Возвращает новый массив, элементы которого — это все те элементы из self, для которых блок возвращает false или nil:

a = [:foo, 'bar', 2, 'bat']
a1 = a.reject {|element| element.to_s.start_with?('b') }
a1 # => [:foo, 2]

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a.reject # => #<Enumerator: [:foo, "bar", 2]:reject>
reject! {|element| ... } → self or nil Show source
reject! → new_enumerator
static VALUE
rb_ary_reject_bang(VALUE ary)
{
    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    rb_ary_modify(ary);
    return ary_reject_bang(ary);
}

Удаляет каждый элемент, для которого блок возвращает истинное значение.

Возвращает self, если удалены какие-либо элементы:

a = [:foo, 'bar', 2, 'bat']
a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2]

Возвращает nil, если элементы не удалены.

Возвращает новый перечислитель, если блок не задан:

a = [:foo, 'bar', 2]
a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
repeated_combination(n) {|combination| ... } → self Show source
repeated_combination(n) → new_enumerator
static VALUE
rb_ary_repeated_combination(VALUE ary, VALUE num)
{
    long n, i, len;

    n = NUM2LONG(num);                 /* Combination size from argument */
    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size);   /* Return enumerator if no block */
    len = RARRAY_LEN(ary);
    if (n < 0) {
        /* yield nothing */
    }
    else if (n == 0) {
        rb_yield(rb_ary_new2(0));
    }
    else if (n == 1) {
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
        }
    }
    else if (len == 0) {
        /* yield nothing */
    }
    else {
        volatile VALUE t0;
        long *p = ALLOCV_N(long, t0, n);
        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
        RBASIC_CLEAR_CLASS(ary0);

        rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
        ALLOCV_END(t0);
        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
    }
    return ary;
}

Вызывает блок с каждой повторяющейся комбинацией длины n элементов self; каждая комбинация является массивом; возвращает self. Порядок комбинаций неопределен.

Когда заданы блок и положительный целочисленный аргумент n, вызывает блок с каждой n-кортежной повторяющейся комбинацией элементов self. Количество комбинаций равно (n+1)(n+2)/2.

n = 1:

a = [0, 1, 2]
a.repeated_combination(1) {|combination| p combination }

Вывод:

[0]
[1]
[2]

n = 2:

a.repeated_combination(2) {|combination| p combination }

Вывод:

[0, 0]
[0, 1]
[0, 2]
[1, 1]
[1, 2]
[2, 2]

Если n равно нулю, вызывает блок один раз с пустым массивом.

Если n отрицательно, блок не вызывается:

a.repeated_combination(-1) {|combination| fail 'Cannot happen' }

Возвращает новый перечислитель, если блок не задан:

a = [0, 1, 2]
a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>

Используя перечислители, удобно показать комбинации и подсчеты для некоторых значений n:

e = a.repeated_combination(0)
e.size # => 1
e.to_a # => [[]]
e = a.repeated_combination(1)
e.size # => 3
e.to_a # => [[0], [1], [2]]
e = a.repeated_combination(2)
e.size # => 6
e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
repeated_permutation(n) {|permutation| ... } → self Show source
repeated_permutation(n) → new_enumerator
static VALUE
rb_ary_repeated_permutation(VALUE ary, VALUE num)
{
    long r, n, i;

    n = RARRAY_LEN(ary);                  /* Array length */
    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size);      /* Return Enumerator if no block */
    r = NUM2LONG(num);                    /* Permutation size from argument */

    if (r < 0) {
        /* no permutations: yield nothing */
    }
    else if (r == 0) { /* exactly one permutation: the zero-length array */
        rb_yield(rb_ary_new2(0));
    }
    else if (r == 1) { /* this is a special, easy case */
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
        }
    }
    else {             /* this is the general case */
        volatile VALUE t0;
        long *p = ALLOCV_N(long, t0, r);
        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
        RBASIC_CLEAR_CLASS(ary0);

        rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
        ALLOCV_END(t0);
        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
    }
    return ary;
}

Вызывает блок с каждой повторяющейся перестановкой длины n элементов self; каждая перестановка является массивом; возвращает self. Порядок перестановок неопределен.

Когда заданы блок и положительный целочисленный аргумент n, вызывает блок с каждой n-кортежной повторяющейся перестановкой элементов self. Количество перестановок равно self.size**n.

n = 1:

a = [0, 1, 2]
a.repeated_permutation(1) {|permutation| p permutation }

Вывод:

[0]
[1]
[2]

n = 2:

a.repeated_permutation(2) {|permutation| p permutation }

Вывод:

[0, 0]
[0, 1]
[0, 2]
[1, 0]
[1, 1]
[1, 2]
[2, 0]
[2, 1]
[2, 2]

Если n равно нулю, вызывает блок один раз с пустым массивом.

Если n отрицательно, блок не вызывается:

a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' }

Возвращает новый перечислитель, если блок не задан:

a = [0, 1, 2]
a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>

Используя перечислители, удобно показать перестановки и подсчеты для некоторых значений n:

e = a.repeated_permutation(0)
e.size # => 1
e.to_a # => [[]]
e = a.repeated_permutation(1)
e.size # => 3
e.to_a # => [[0], [1], [2]]
e = a.repeated_permutation(2)
e.size # => 9
e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
replace(other_array) → self

Заменяет содержимое self содержимым other_array; возвращает self:

a = [:foo, 'bar', 2]
a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
Псевдоним для: initialize_copy
reverse → new_array Show source
static VALUE
rb_ary_reverse_m(VALUE ary)
{
    long len = RARRAY_LEN(ary);
    VALUE dup = rb_ary_new2(len);

    if (len > 0) {
        const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
        VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
        do *p2-- = *p1++; while (--len > 0);
    }
    ARY_SET_LEN(dup, RARRAY_LEN(ary));
    return dup;
}

Возвращает новый массив с элементами self в обратном порядке.

a = ['foo', 'bar', 'two']
a1 = a.reverse
a1 # => ["two", "bar", "foo"]
reverse! → self Show source
static VALUE
rb_ary_reverse_bang(VALUE ary)
{
    return rb_ary_reverse(ary);
}

Разворачивает self на месте:

a = ['foo', 'bar', 'two']
a.reverse! # => ["two", "bar", "foo"]
reverse_each {|element| ... } → self Показать исходный код
reverse_each → Enumerator
static VALUE
rb_ary_reverse_each(VALUE ary)
{
    long len;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    len = RARRAY_LEN(ary);
    while (len--) {
        long nlen;
        rb_yield(RARRAY_AREF(ary, len));
        nlen = RARRAY_LEN(ary);
        if (nlen < len) {
            len = nlen;
        }
    }
    return ary;
}

Итерирует элементы массива в обратном порядке.

Если блок задан, передаёт каждый элемент в обратном порядке блоку; возвращает self:

a = [:foo, 'bar', 2]
a.reverse_each {|element|  puts "#{element.class} #{element}" }

Вывод:

Integer 2
String bar
Symbol foo

Разрешает изменение массива во время итерации:

a = [:foo, 'bar', 2]
a.reverse_each {|element| puts element; a.clear if element.to_s.start_with?('b') }

Вывод:

2
bar

Если блок не задан, возвращает новый Enumerator:

a = [:foo, 'bar', 2]
e = a.reverse_each
e # => #<Enumerator: [:foo, "bar", 2]:reverse_each>
a1 = e.each {|element|  puts "#{element.class} #{element}" }

Вывод:

Integer 2
String bar
Symbol foo

Связанные: each, each_index.

rindex(object) → integer or nil Показать исходный код
rindex {|element| ... } → integer or nil
rindex → new_enumerator
static VALUE
rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
{
    VALUE val;
    long i = RARRAY_LEN(ary), len;

    if (argc == 0) {
        RETURN_ENUMERATOR(ary, 0, 0);
        while (i--) {
            if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
                return LONG2NUM(i);
            if (i > (len = RARRAY_LEN(ary))) {
                i = len;
            }
        }
        return Qnil;
    }
    rb_check_arity(argc, 0, 1);
    val = argv[0];
    if (rb_block_given_p())
        rb_warn("given block not used");
    while (i--) {
        VALUE e = RARRAY_AREF(ary, i);
        if (rb_equal(e, val)) {
            return LONG2NUM(i);
        }
        if (i > RARRAY_LEN(ary)) {
            break;
        }
    }
    return Qnil;
}

Возвращает индекс последнего элемента, для которого object == element.

Когда задан аргумент object но нет блока, возвращает индекс последнего такого элемента, найденного:

a = [:foo, 'bar', 2, 'bar']
a.rindex('bar') # => 3

Возвращает nil если такой объект не найден.

Когда задан блок, но нет аргумента, вызывает блок с каждым последующим элементом; возвращает индекс последнего элемента, для которого блок возвращает истинное значение:

a = [:foo, 'bar', 2, 'bar']
a.rindex {|element| element == 'bar' } # => 3

Возвращает nil если блок никогда не возвращает истинное значение.

Когда ни аргумент, ни блок не заданы, возвращает новый Enumerator:

a = [:foo, 'bar', 2, 'bar']
e = a.rindex
e # => #<Enumerator: [:foo, "bar", 2, "bar"]:rindex>
e.each {|element| element == 'bar' } # => 3

Связанные: index.

rotate → new_array Показать исходный код
rotate(count) → new_array
static VALUE
rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
{
    VALUE rotated;
    const VALUE *ptr;
    long len;
    long cnt = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);

    len = RARRAY_LEN(ary);
    rotated = rb_ary_new2(len);
    if (len > 0) {
        cnt = rotate_count(cnt, len);
        ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
        len -= cnt;
        ary_memcpy(rotated, 0, len, ptr + cnt);
        ary_memcpy(rotated, len, cnt, ptr);
    }
    ARY_SET_LEN(rotated, RARRAY_LEN(ary));
    return rotated;
}

Возвращает новый массив, образованный из self с элементами, повернутыми с одного конца на другой.

Когда аргумент не задан, возвращает новый массив, похожий на self, за исключением того, что первый элемент был повернут в последнюю позицию:

a = [:foo, 'bar', 2, 'bar']
a1 = a.rotate
a1 # => ["bar", 2, "bar", :foo]

Когда задан неотрицательное целое число count, возвращает новый массив с count элементами, повернутыми с начала до конца:

a = [:foo, 'bar', 2]
a1 = a.rotate(2)
a1 # => [2, :foo, "bar"]

Если count большое, использует count % array.size в качестве счётчика:

a = [:foo, 'bar', 2]
a1 = a.rotate(20)
a1 # => [2, :foo, "bar"]

Если count равно нулю, возвращает копию self, без изменений:

a = [:foo, 'bar', 2]
a1 = a.rotate(0)
a1 # => [:foo, "bar", 2]

Когда задано отрицательное целое число count, вращает в противоположном направлении, с конца до начала:

a = [:foo, 'bar', 2]
a1 = a.rotate(-2)
a1 # => ["bar", 2, :foo]

Если count мало (далеко от нуля), использует count % array.size в качестве счётчика:

a = [:foo, 'bar', 2]
a1 = a.rotate(-5)
a1 # => ["bar", 2, :foo]
rotate! → self Показать исходный код
rotate!(count) → self
static VALUE
rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
{
    long n = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
    rb_ary_rotate(ary, n);
    return ary;
}

Поворачивает self на месте, перемещая элементы с одного конца на другой; возвращает self.

Когда аргумент не задан, поворачивает первый элемент в последнюю позицию:

a = [:foo, 'bar', 2, 'bar']
a.rotate! # => ["bar", 2, "bar", :foo]

Когда задано неотрицательное целое число count, поворачивает count элементы с начала до конца:

a = [:foo, 'bar', 2]
a.rotate!(2)
a # => [2, :foo, "bar"]

Если count большое, использует count % array.size в качестве счётчика:

a = [:foo, 'bar', 2]
a.rotate!(20)
a # => [2, :foo, "bar"]

Если count равно нулю, возвращает self без изменений:

a = [:foo, 'bar', 2]
a.rotate!(0)
a # => [:foo, "bar", 2]

Когда задано отрицательное Integer count, поворачивает в противоположном направлении, с конца до начала:

a = [:foo, 'bar', 2]
a.rotate!(-2)
a # => ["bar", 2, :foo]

Если count мало (далеко от нуля), использует count % array.size в качестве счётчика:

a = [:foo, 'bar', 2]
a.rotate!(-5)
a # => ["bar", 2, :foo]
sample(random: Random) → object Показать исходный код
sample(n, random: Random) → new_ary
# File array.rb, line 58
def sample(n = (ary = false), random: Random)
  Primitive.rb_ary_sample(random, n, ary)
end

Возвращает случайные элементы из self.

Когда нет аргументов, возвращает случайный элемент из self:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.sample # => 3
a.sample # => 8

Если self пустой, возвращает nil.

Когда аргумент n задан, возвращает новый массив, содержащий n случайных элементов из self:

a.sample(3) # => [8, 9, 2]
a.sample(6) # => [9, 6, 10, 3, 1, 4]

Возвращает не более a.size элементов (потому что новые дубликаты не вводятся):

a.sample(a.size * 2) # => [6, 4, 1, 8, 5, 9, 10, 2, 3, 7]

Но self может содержать дубликаты:

a = [1, 1, 1, 2, 2, 3]
a.sample(a.size * 2) # => [1, 1, 3, 2, 1, 2]

Возвращает новый пустой массив, если self пустой.

Необязательный аргумент random будет использован как генератор случайных чисел:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.sample(random: Random.new(1))     #=> 6
a.sample(4, random: Random.new(1))  #=> [6, 10, 9, 2]
select {|element| ... } → new_array Показать исходный код
select → new_enumerator
static VALUE
rb_ary_select(VALUE ary)
{
    VALUE result;
    long i;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    result = rb_ary_new2(RARRAY_LEN(ary));
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
            rb_ary_push(result, rb_ary_elt(ary, i));
        }
    }
    return result;
}

Вызывает блок, если задан, с каждым элементом self; возвращает новый массив, содержащий те элементы self для которых блок возвращает истинное значение:

a = [:foo, 'bar', 2, :bam]
a1 = a.select {|element| element.to_s.start_with?('b') }
a1 # => ["bar", :bam]

Возвращает новый Enumerator если блок не задан:

a = [:foo, 'bar', 2, :bam]
a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>

Array#filter является псевдонимом для Array#select.

Также алиасировано как: filter
select! {|element| ... } → self or nil Показать исходный код
select! → new_enumerator
static VALUE
rb_ary_select_bang(VALUE ary)
{
    struct select_bang_arg args;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    rb_ary_modify(ary);

    args.ary = ary;
    args.len[0] = args.len[1] = 0;
    return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
}

Вызывает блок, если задан, с каждым элементом self; удаляет из self те элементы, для которых блок возвращает false или nil.

Возвращает self если какие-либо элементы были удалены:

a = [:foo, 'bar', 2, :bam]
a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]

Возвращает nil если элементы не удалялись.

Возвращает новый Enumerator если блок не задан:

a = [:foo, 'bar', 2, :bam]
a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>

Array#filter! является псевдонимом для Array#select!.

Также алиасировано как: filter!
shelljoin → string Показать исходный код
# File lib/shellwords.rb, line 237
def shelljoin
  Shellwords.join(self)
end

Создаёт строку командной строки из списка аргументов array объединяя все элементы, экранированные для оболочки Bourne, разделённые пробелом.

См. Shellwords.shelljoin для деталей.

shift → object or nil Показать исходный код
shift(n) → new_array
static VALUE
rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
{
    VALUE result;
    long n;

    if (argc == 0) {
        return rb_ary_shift(ary);
    }

    rb_ary_modify_check(ary);
    result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
    n = RARRAY_LEN(result);
    rb_ary_behead(ary,n);

    return result;
}

Удаляет и возвращает ведущие элементы.

Если аргумент не задан, удаляет и возвращает первый элемент:

a = [:foo, 'bar', 2]
a.shift # => :foo
a # => ['bar', 2]

Возвращает nil если self пустой.

Если задан положительный целое число аргумент n удаляет первые n элементы; возвращает эти элементы в новом массиве:

a = [:foo, 'bar', 2]
a.shift(2) # => [:foo, 'bar']
a # => [2]

Если n столь же велик или больше, чем self.length, удаляет все элементы; возвращает эти элементы в новом массиве:

a = [:foo, 'bar', 2]
a.shift(3) # => [:foo, 'bar', 2]

Если n равно нулю, возвращает новый пустой массив; self не изменяется.

Связанные: push, pop, unshift.

shuffle(random: Random) → new_ary Показать исходный код
# File array.rb, line 26
def shuffle(random: Random)
  Primitive.rb_ary_shuffle(random)
end

Возвращает новый массив с элементами self перемешанными.

a = [1, 2, 3] #=> [1, 2, 3]
a.shuffle     #=> [2, 3, 1]
a             #=> [1, 2, 3]

Необязательный аргумент random будет использован как генератор случайных чисел:

a.shuffle(random: Random.new(1))  #=> [1, 3, 2]
shuffle!(random: Random) → array Показать исходный код
# File array.rb, line 12
def shuffle!(random: Random)
  Primitive.rb_ary_shuffle_bang(random)
end

Перемешивает элементы self на месте.

a = [1, 2, 3] #=> [1, 2, 3]
a.shuffle!    #=> [2, 3, 1]
a             #=> [2, 3, 1]

Необязательный аргумент random будет использован в качестве генератора псевдослучайных чисел:

a.shuffle!(random: Random.new(1))  #=> [1, 3, 2]

Возвращает количество элементов в self.

Псевдоним для: length
slice(index) → объект или nil
slice(start, length) → объект или nil
slice(range) → объект или nil
slice(aseq) → объект или nil

Возвращает элементы из self; не изменяет self.

Когда задан единственный целочисленный аргумент index, возвращает элемент с смещением index:

a = [:foo, 'bar', 2]
a[0] # => :foo
a[2] # => 2
a # => [:foo, "bar", 2]

Если index отрицательное, подсчет ведётся относительно конца self:

a = [:foo, 'bar', 2]
a[-1] # => 2
a[-2] # => "bar"

Если index выходит за пределы диапазона, возвращает nil.

Когда заданы два целочисленных аргумента start и length, возвращает новый массив размером length, содержащий последовательные элементы, начиная с смещения start:

a = [:foo, 'bar', 2]
a[0, 2] # => [:foo, "bar"]
a[1, 2] # => ["bar", 2]

Если start + length больше self.length, возвращает все элементы от смещения start до конца:

a = [:foo, 'bar', 2]
a[0, 4] # => [:foo, "bar", 2]
a[1, 3] # => ["bar", 2]
a[2, 2] # => [2]

Если start == self.size и length >= 0, возвращает новый пустой массив.

Если length отрицательное, возвращает nil.

При задании единственного аргумента Range range, range.min обрабатывается как start выше, а range.size как length выше:

a = [:foo, 'bar', 2]
a[0..1] # => [:foo, "bar"]
a[1..2] # => ["bar", 2]

Особый случай: Если range.start == a.size, возвращает новый пустой массив.

Если range.end отрицательное, вычисляет конечный индекс с конца:

a = [:foo, 'bar', 2]
a[0..-1] # => [:foo, "bar", 2]
a[0..-2] # => [:foo, "bar"]
a[0..-3] # => [:foo]

Если range.start отрицательное, вычисляет начальный индекс с конца:

a = [:foo, 'bar', 2]
a[-1..2] # => [2]
a[-2..2] # => ["bar", 2]
a[-3..2] # => [:foo, "bar", 2]

Если range.start больше размера массива, возвращает nil.

a = [:foo, 'bar', 2]
a[4..1] # => nil
a[4..0] # => nil
a[4..-1] # => nil

При задании единственного аргумента Enumerator::ArithmeticSequence aseq, возвращает массив Array элементов, соответствующих индексам, сгенерированным последовательностью.

a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..).step(2)] # => ["data1", "data2", "data3"]

В отличие от среза с диапазоном, если начало или конец арифметической последовательности больше размера массива, генерируется RangeError.

a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..11).step(2)]
# RangeError (((1..11).step(2)) out of range)
a[(7..).step(2)]
# RangeError (((7..).step(2)) out of range)

Если задан один аргумент, и его тип не указан в списке, пытается преобразовать его в Integer, и генерирует исключение, если это невозможно:

a = [:foo, 'bar', 2]
# Raises TypeError (no implicit conversion of Symbol into Integer):
a[:foo]

Array#slice является псевдонимом для Array#[].

Псевдоним для: []
slice!(n) → объект или nil Показать исходный код
slice!(start, length) → новый_массив или nil
slice!(range) → новый_массив или nil
static VALUE
rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
{
    VALUE arg1;
    long pos, len;

    rb_ary_modify_check(ary);
    rb_check_arity(argc, 1, 2);
    arg1 = argv[0];

    if (argc == 2) {
        pos = NUM2LONG(argv[0]);
        len = NUM2LONG(argv[1]);
        return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
    }

    if (!FIXNUM_P(arg1)) {
        switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
          case Qtrue:
            /* valid range */
            return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
          case Qnil:
            /* invalid range */
            return Qnil;
          default:
            /* not a range */
            break;
        }
    }

    return rb_ary_delete_at(ary, NUM2LONG(arg1));
}

Удаляет и возвращает элементы из self.

Когда единственный аргумент — целое число n, удаляет и возвращает n-ый элемент в self:

a = [:foo, 'bar', 2]
a.slice!(1) # => "bar"
a # => [:foo, 2]

Если n отрицательное, подсчёт ведётся с конца self:

a = [:foo, 'bar', 2]
a.slice!(-1) # => 2
a # => [:foo, "bar"]

Если n выходит за пределы диапазона, возвращает nil.

Когда единственные аргументы — целые числа start и length, удаляет length элементов из self, начиная со смещения start; возвращает удалённые объекты в новом массиве:

a = [:foo, 'bar', 2]
a.slice!(0, 2) # => [:foo, "bar"]
a # => [2]

Если start + length превышает размер массива, удаляет и возвращает все элементы от смещения start до конца:

a = [:foo, 'bar', 2]
a.slice!(1, 50) # => ["bar", 2]
a # => [:foo]

Если start == a.size и length неотрицательные, возвращает новый пустой массив.

Если length отрицательное, возвращает nil.

Когда единственный аргумент — объект Range range, range.min обрабатывается как start выше, а range.size как length выше:

a = [:foo, 'bar', 2]
 a.slice!(1..2) # => ["bar", 2]
a # => [:foo]

Если range.start == a.size, возвращает новый пустой массив.

Если range.start больше размера массива, возвращает nil.

Если range.end отрицательное, подсчёт ведётся с конца массива:

a = [:foo, 'bar', 2]
a.slice!(0..-2) # => [:foo, "bar"]
a # => [2]

Если range.start отрицательное, начальный индекс вычисляется с конца массива:

a = [:foo, 'bar', 2]
a.slice!(-2..2) # => ["bar", 2]
a # => [:foo]
sort → новый_массив Показать исходный код
sort {|a, b| ... } → новый_массив
VALUE
rb_ary_sort(VALUE ary)
{
    ary = rb_ary_dup(ary);
    rb_ary_sort_bang(ary);
    return ary;
}

Возвращает новый массив, элементы которого взяты из self, отсортированные.

Без блока сравнивает элементы с использованием оператора <=> (см. Comparable):

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort
a1 # => ["a", "b", "c", "d", "e"]

С блоком вызывает блок с каждой парой элементов; для каждой пары элементов a и b, блок должен возвращать целое число:

  • Отрицательное, когда b должен следовать за a.

  • Ноль, когда a и b эквивалентны.

  • Положительное, когда a должен следовать за b.

Пример:

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| a <=> b }
a1 # => ["a", "b", "c", "d", "e"]
a2 = a.sort {|a, b| b <=> a }
a2 # => ["e", "d", "c", "b", "a"]

Когда блок возвращает ноль, порядок a и b не определён и может быть неустойчивым:

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| 0 }
a1 # =>  ["c", "e", "b", "d", "a"]

Связанно с: Enumerable#sort_by.

sort! → self Показать исходный код
sort! {|a, b| ... } → self
VALUE
rb_ary_sort_bang(VALUE ary)
{
    rb_ary_modify(ary);
    assert(!ARY_SHARED_P(ary));
    if (RARRAY_LEN(ary) > 1) {
        VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
        struct ary_sort_data data;
        long len = RARRAY_LEN(ary);
        RBASIC_CLEAR_CLASS(tmp);
        data.ary = tmp;
        data.cmp_opt.opt_methods = 0;
        data.cmp_opt.opt_inited = 0;
        RARRAY_PTR_USE(tmp, ptr, {
            ruby_qsort(ptr, len, sizeof(VALUE),
                       rb_block_given_p()?sort_1:sort_2, &data);
        }); /* WB: no new reference */
        rb_ary_modify(ary);
        if (ARY_EMBED_P(tmp)) {
            if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
                rb_ary_unshare(ary);
                FL_SET_EMBED(ary);
            }
            ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
            ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
        }
        else {
            if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
                FL_UNSET_SHARED(ary);
                ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
            }
            else {
                assert(!ARY_SHARED_P(tmp));
                if (ARY_EMBED_P(ary)) {
                    FL_UNSET_EMBED(ary);
                }
                else if (ARY_SHARED_P(ary)) {
                    /* ary might be destructively operated in the given block */
                    rb_ary_unshare(ary);
                }
                else {
                    ary_heap_free(ary);
                }
                ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
                ARY_SET_HEAP_LEN(ary, len);
                ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
            }
            /* tmp was lost ownership for the ptr */
            FL_UNSET(tmp, FL_FREEZE);
            FL_SET_EMBED(tmp);
            ARY_SET_EMBED_LEN(tmp, 0);
            FL_SET(tmp, FL_FREEZE);
        }
        /* tmp will be GC'ed. */
        RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
    }
    ary_verify(ary);
    return ary;
}

Возвращает self с отсортированными на месте элементами.

Без блока сравнивает элементы с использованием оператора <=> (см. Comparable):

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a.sort!
a # => ["a", "b", "c", "d", "e"]

С блоком вызывает блок с каждой парой элементов; для каждой пары элементов a и b, блок должен возвращать целое число:

  • Отрицательное, когда b должен следовать за a.

  • Ноль, когда a и b эквивалентны.

  • Положительное, когда a должен следовать за b.

Пример:

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a.sort! {|a, b| a <=> b }
a # => ["a", "b", "c", "d", "e"]
a.sort! {|a, b| b <=> a }
a # => ["e", "d", "c", "b", "a"]

Когда блок возвращает ноль, порядок a и b не определён и может быть неустойчивым:

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a.sort! {|a, b| 0 }
a # => ["d", "e", "c", "a", "b"]
sort_by! {|element| ... } → self Показать исходный код
sort_by! → новый_перечислитель
static VALUE
rb_ary_sort_by_bang(VALUE ary)
{
    VALUE sorted;

    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
    rb_ary_modify(ary);
    sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
    rb_ary_replace(ary, sorted);
    return ary;
}

Сортирует элементы self на месте, используя порядок, определяемый блоком; возвращает self.

Вызывает блок с каждым последующим элементом; сортирует элементы на основе значений, возвращённых из блока.

Для дубликатов, возвращённых блоком, порядок не определён и может быть неустойчивым.

В этом примере строки сортируются по их размерам:

a = ['aaaa', 'bbb', 'cc', 'd']
a.sort_by! {|element| element.size }
a # => ["d", "cc", "bbb", "aaaa"]

Возвращает новый перечислитель, если блок не задан:

a = ['aaaa', 'bbb', 'cc', 'd']
a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!>
sum(init = 0) → object Показать исходный код
sum(init = 0) {|element| ... } → object
static VALUE
rb_ary_sum(int argc, VALUE *argv, VALUE ary)
{
    VALUE e, v, r;
    long i, n;
    int block_given;

    v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));

    block_given = rb_block_given_p();

    if (RARRAY_LEN(ary) == 0)
        return v;

    n = 0;
    r = Qundef;
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        e = RARRAY_AREF(ary, i);
        if (block_given)
            e = rb_yield(e);
        if (FIXNUM_P(e)) {
            n += FIX2LONG(e); /* should not overflow long type */
            if (!FIXABLE(n)) {
                v = rb_big_plus(LONG2NUM(n), v);
                n = 0;
            }
        }
        else if (RB_TYPE_P(e, T_BIGNUM))
            v = rb_big_plus(e, v);
        else if (RB_TYPE_P(e, T_RATIONAL)) {
            if (r == Qundef)
                r = e;
            else
                r = rb_rational_plus(r, e);
        }
        else
            goto not_exact;
    }
    v = finish_exact_sum(n, r, v, argc!=0);
    return v;

  not_exact:
    v = finish_exact_sum(n, r, v, i!=0);

    if (RB_FLOAT_TYPE_P(e)) {
        /*
         * Kahan-Babuska balancing compensated summation algorithm
         * See https://link.springer.com/article/10.1007/s00607-005-0139-x
         */
        double f, c;
        double x, t;

        f = NUM2DBL(v);
        c = 0.0;
        goto has_float_value;
        for (; i < RARRAY_LEN(ary); i++) {
            e = RARRAY_AREF(ary, i);
            if (block_given)
                e = rb_yield(e);
            if (RB_FLOAT_TYPE_P(e))
              has_float_value:
                x = RFLOAT_VALUE(e);
            else if (FIXNUM_P(e))
                x = FIX2LONG(e);
            else if (RB_TYPE_P(e, T_BIGNUM))
                x = rb_big2dbl(e);
            else if (RB_TYPE_P(e, T_RATIONAL))
                x = rb_num2dbl(e);
            else
                goto not_float;

            if (isnan(f)) continue;
            if (isnan(x)) {
                f = x;
                continue;
            }
            if (isinf(x)) {
                if (isinf(f) && signbit(x) != signbit(f))
                    f = NAN;
                else
                    f = x;
                continue;
            }
            if (isinf(f)) continue;

            t = f + x;
            if (fabs(f) >= fabs(x))
                c += ((f - t) + x);
            else
                c += ((x - t) + f);
            f = t;
        }
        f += c;
        return DBL2NUM(f);

      not_float:
        v = DBL2NUM(f);
    }

    goto has_some_value;
    for (; i < RARRAY_LEN(ary); i++) {
        e = RARRAY_AREF(ary, i);
        if (block_given)
            e = rb_yield(e);
      has_some_value:
        v = rb_funcall(v, idPLUS, 1, e);
    }
    return v;
}

При отсутствии блока возвращает объект, эквивалентный:

sum = init
array.each {|element| sum += element }
sum

Например, [e1, e2, e3].sum возвращает </tt>init + e1 + e2 + e3</tt>.

Примеры:

a = [0, 1, 2, 3]
a.sum # => 6
a.sum(100) # => 106

Элементы необязательно должны быть числовыми, но должны быть +-совместимыми друг с другом и с init:

a = ['abc', 'def', 'ghi']
a.sum('jkl') # => "jklabcdefghi"

При наличии блока он вызывается для каждого элемента, а значение, возвращаемое блоком (вместо самого элемента), используется в качестве слагаемого:

a = ['zero', 1, :two]
s = a.sum('Coerced and concatenated: ') {|element| element.to_s }
s # => "Coerced and concatenated: zero1two"

Примечания:

  • Array#join и Array#flatten могут быть быстрее, чем Array#sum, для массива строк или массива массивов.

  • Array#sum метод может не учитывать переопределение метода «+» для таких методов, как Integer#+.

take(n) → new_array Показать исходный код
static VALUE
rb_ary_take(VALUE obj, VALUE n)
{
    long len = NUM2LONG(n);
    if (len < 0) {
        rb_raise(rb_eArgError, "attempt to take negative size");
    }
    return rb_ary_subseq(obj, 0, len);
}

Возвращает новый массив, содержащий первые n элементов массива self, где n — целое неотрицательное число; не изменяет self.

Примеры:

a = [0, 1, 2, 3, 4, 5]
a.take(1) # => [0]
a.take(2) # => [0, 1]
a.take(50) # => [0, 1, 2, 3, 4, 5]
a # => [0, 1, 2, 3, 4, 5]
take_while {|element| ... } → new_array Показать исходный код
take_while → new_enumerator
static VALUE
rb_ary_take_while(VALUE ary)
{
    long i;

    RETURN_ENUMERATOR(ary, 0, 0);
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
    }
    return rb_ary_take(ary, LONG2FIX(i));
}

Возвращает новый массив, содержащий нуль или более ведущих элементов массива self; не изменяет self.

При наличии блока, вызывает блок для каждого последующего элемента массива self; прекращает выполнение, если блок возвращает false или nil; возвращает новый Array, содержащий те элементы, для которых блок возвратил истинное значение:

a = [0, 1, 2, 3, 4, 5]
a.take_while {|element| element < 3 } # => [0, 1, 2]
a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5]
a # => [0, 1, 2, 3, 4, 5]

При отсутствии блока возвращает новый перечислитель:

[0, 1].take_while # => #<Enumerator: [0, 1]:take_while>
to_a → self or new_array Показать исходный код
static VALUE
rb_ary_to_a(VALUE ary)
{
    if (rb_obj_class(ary) != rb_cArray) {
        VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
        rb_ary_replace(dup, ary);
        return dup;
    }
    return ary;
}

Когда self является экземпляром массива, возвращает self:

a = [:foo, 'bar', 2]
a.to_a # => [:foo, "bar", 2]

В противном случае возвращает новый массив, содержащий элементы self:

class MyArray < Array; end
a = MyArray.new(['foo', 'bar', 'two'])
a.instance_of?(Array) # => false
a.kind_of?(Array) # => true
a1 = a.to_a
a1 # => ["foo", "bar", "two"]
a1.class # => Array # Not MyArray
to_ary → self Показать исходный код
static VALUE
rb_ary_to_ary_m(VALUE ary)
{
    return ary;
}

Возвращает self.

to_h → new_hash Показать исходный код
to_h {|item| ... } → new_hash
static VALUE
rb_ary_to_h(VALUE ary)
{
    long i;
    VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));
    int block_given = rb_block_given_p();

    for (i=0; i<RARRAY_LEN(ary); i++) {
        const VALUE e = rb_ary_elt(ary, i);
        const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
        const VALUE key_value_pair = rb_check_array_type(elt);
        if (NIL_P(key_value_pair)) {
            rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
                     rb_obj_class(elt), i);
        }
        if (RARRAY_LEN(key_value_pair) != 2) {
            rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
                i, RARRAY_LEN(key_value_pair));
        }
        rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
    }
    return hash;
}

Возвращает новый словарь, сформированный из self.

При наличии блока, вызывает блок с каждым элементом массива; блок должен возвращать массив из двух элементов, которые образуют пару ключ-значение в возвращаемом словаре:

a = ['foo', :bar, 1, [2, 3], {baz: 4}]
h = a.to_h {|item| [item, item] }
h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}}

Если блок не указан, self должен быть массивом подмассивов по два элемента, каждый из которых образует пару ключ-значение в новом словаре:

[].to_h # => {}
a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
h = a.to_h
h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}

Возвращает новую строку, сформированную путём вызова метода #inspect для каждого элемента массива:

a = [:foo, 'bar', 2]
a.inspect # => "[:foo, \"bar\", 2]"

Array#to_s является псевдонимом для Array#inspect.

Псевдоним для: inspect
transpose → new_array Показать исходный код
static VALUE
rb_ary_transpose(VALUE ary)
{
    long elen = -1, alen, i, j;
    VALUE tmp, result = 0;

    alen = RARRAY_LEN(ary);
    if (alen == 0) return rb_ary_dup(ary);
    for (i=0; i<alen; i++) {
        tmp = to_ary(rb_ary_elt(ary, i));
        if (elen < 0) {                /* first element */
            elen = RARRAY_LEN(tmp);
            result = rb_ary_new2(elen);
            for (j=0; j<elen; j++) {
                rb_ary_store(result, j, rb_ary_new2(alen));
            }
        }
        else if (elen != RARRAY_LEN(tmp)) {
            rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
                     RARRAY_LEN(tmp), elen);
        }
        for (j=0; j<elen; j++) {
            rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
        }
    }
    return result;
}

Транспонирует строки и столбцы в массиве массивов; вложенные массивы должны иметь одинаковый размер:

a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
union(*other_arrays) → new_array Показать исходный код
static VALUE
rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
{
    int i;
    long sum;
    VALUE hash, ary_union;

    sum = RARRAY_LEN(ary);
    for (i = 0; i < argc; i++) {
        argv[i] = to_ary(argv[i]);
        sum += RARRAY_LEN(argv[i]);
    }

    if (sum <= SMALL_ARRAY_LEN) {
        ary_union = rb_ary_new();

        rb_ary_union(ary_union, ary);
        for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);

        return ary_union;
    }

    hash = ary_make_hash(ary);
    for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);

    ary_union = rb_hash_values(hash);
    ary_recycle_hash(hash);
    return ary_union;
}

Возвращает новый массив, являющийся объединением self и всех заданных массивов other_arrays; дубликаты удаляются; порядок сохраняется; элементы сравниваются с использованием eql?:

[0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3]
[0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3]

Возвращает копию self если не заданы аргументы.

Связанное: Array#|.

uniq → new_array Показать исходный код
uniq {|element| ... } → new_array
static VALUE
rb_ary_uniq(VALUE ary)
{
    VALUE hash, uniq;

    if (RARRAY_LEN(ary) <= 1) {
        hash = 0;
        uniq = rb_ary_dup(ary);
    }
    else if (rb_block_given_p()) {
        hash = ary_make_hash_by(ary);
        uniq = rb_hash_values(hash);
    }
    else {
        hash = ary_make_hash(ary);
        uniq = rb_hash_values(hash);
    }
    if (hash) {
        ary_recycle_hash(hash);
    }

    return uniq;
}

Возвращает новый массив, содержащий те элементы из self, которые не являются дубликатами, при этом всегда сохраняется первое вхождение.

Без блока определяет и опускает дубликаты, используя метод eql? для сравнения.

a = [0, 0, 1, 1, 2, 2]
a.uniq # => [0, 1, 2]

При наличии блока, вызывает блок для каждого элемента; определяет (используя метод eql?) и опускает значения-дубликаты, то есть те элементы, для которых блок возвращает одинаковые значения:

a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
uniq! → self or nil Показать исходный код
uniq! {|element| ... } → self or nil
static VALUE
rb_ary_uniq_bang(VALUE ary)
{
    VALUE hash;
    long hash_size;

    rb_ary_modify_check(ary);
    if (RARRAY_LEN(ary) <= 1)
        return Qnil;
    if (rb_block_given_p())
        hash = ary_make_hash_by(ary);
    else
        hash = ary_make_hash(ary);

    hash_size = RHASH_SIZE(hash);
    if (RARRAY_LEN(ary) == hash_size) {
        return Qnil;
    }
    rb_ary_modify_check(ary);
    ARY_SET_LEN(ary, 0);
    if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
        rb_ary_unshare(ary);
        FL_SET_EMBED(ary);
    }
    ary_resize_capa(ary, hash_size);
    rb_hash_foreach(hash, push_value, ary);
    ary_recycle_hash(hash);

    return ary;
}

Удаляет повторяющиеся элементы из self, при этом всегда сохраняется первое вхождение; возвращает self если какие-либо элементы удалены, nil в противном случае.

Без блока определяет и удаляет элементы, используя метод eql? для сравнения.

Возвращает self если какие-либо элементы были удалены:

a = [0, 0, 1, 1, 2, 2]
a.uniq! # => [0, 1, 2]

Возвращает nil если элементы не были удалены.

При наличии блока, вызывает блок для каждого элемента; определяет (используя метод eql?) и удаляет элементы, для которых блок возвращает повторяющиеся значения.

Возвращает self если какие-либо элементы были удалены:

a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq! {|element| element.size } # => ['a', 'aa', 'aaa']

Возвращает nil если элементы не были удалены.

unshift(*objects) → self Показать исходный код
static VALUE
rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
{
    long len = RARRAY_LEN(ary);
    VALUE target_ary;

    if (argc == 0) {
        rb_ary_modify_check(ary);
        return ary;
    }

    target_ary = ary_ensure_room_for_unshift(ary, argc);
    ary_memcpy0(ary, 0, argc, argv, target_ary);
    ARY_SET_LEN(ary, len + argc);
    return ary;
}

Вставляет заданные objects в начало массива self:

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

Array#prepend — псевдоним для Array#unshift.

Связанное: push, pop, shift.

Также псевдоним: prepend
values_at(*indexes) → new_array Показать исходный код
static VALUE
rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
{
    long i, olen = RARRAY_LEN(ary);
    VALUE result = rb_ary_new_capa(argc);
    for (i = 0; i < argc; ++i) {
        append_values_at_single(result, ary, olen, argv[i]);
    }
    RB_GC_GUARD(ary);
    return result;
}

Возвращает новый массив, элементы которого являются элементами массива self по заданным целочисленным индексам indexes.

Для каждого положительного index, возвращает элемент по смещению index:

a = [:foo, 'bar', 2]
a.values_at(0, 2) # => [:foo, 2]

Заданные indexes могут быть в любом порядке и повторяться:

a = [:foo, 'bar', 2]
a.values_at(2, 0, 1, 0, 2) # => [2, :foo, "bar", :foo, 2]

Возвращает nil для index, превышающего максимальный индекс:

a = [:foo, 'bar', 2]
a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil]

Возвращает новый пустой массив, если аргументы не заданы.

Для каждого отрицательного index, отсчёт ведётся от конца массива:

a = [:foo, 'bar', 2]
a.values_at(-1, -3) # => [2, :foo]

Возвращает nil для index, меньшего минимального индекса:

a = [:foo, 'bar', 2]
a.values_at(0, -5, 1, -6, 2) # => [:foo, nil, "bar", nil, 2]

Заданные indexes могут иметь смесь знаков:

a = [:foo, 'bar', 2]
a.values_at(0, -2, 1, -1) # => [:foo, "bar", "bar", 2]
zip(*other_arrays) → new_array Показать исходный код
zip(*other_arrays) {|other_array| ... } → nil
static VALUE
rb_ary_zip(int argc, VALUE *argv, VALUE ary)
{
    int i, j;
    long len = RARRAY_LEN(ary);
    VALUE result = Qnil;

    for (i=0; i<argc; i++) {
        argv[i] = take_items(argv[i], len);
    }

    if (rb_block_given_p()) {
        int arity = rb_block_arity();

        if (arity > 1) {
            VALUE work, *tmp;

            tmp = ALLOCV_N(VALUE, work, argc+1);

            for (i=0; i<RARRAY_LEN(ary); i++) {
                tmp[0] = RARRAY_AREF(ary, i);
                for (j=0; j<argc; j++) {
                    tmp[j+1] = rb_ary_elt(argv[j], i);
                }
                rb_yield_values2(argc+1, tmp);
            }

            if (work) ALLOCV_END(work);
        }
        else {
            for (i=0; i<RARRAY_LEN(ary); i++) {
                VALUE tmp = rb_ary_new2(argc+1);

                rb_ary_push(tmp, RARRAY_AREF(ary, i));
                for (j=0; j<argc; j++) {
                    rb_ary_push(tmp, rb_ary_elt(argv[j], i));
                }
                rb_yield(tmp);
            }
        }
    }
    else {
        result = rb_ary_new_capa(len);

        for (i=0; i<len; i++) {
            VALUE tmp = rb_ary_new_capa(argc+1);

            rb_ary_push(tmp, RARRAY_AREF(ary, i));
            for (j=0; j<argc; j++) {
                rb_ary_push(tmp, rb_ary_elt(argv[j], i));
            }
            rb_ary_push(result, tmp);
        }
    }

    return result;
}

Если блок не задан, возвращает новый массив new_array размера self.size, элементы которого являются массивами.

Каждый вложенный массив new_array[n] имеет размер other_arrays.size+1, и содержит:

  • n-ый элемент self.

  • n-ый элемент каждого из other_arrays.

Если все other_arrays и self имеют одинаковый размер:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]

Если какой-либо массив в other_arrays меньше, чем self, заполняется до self.size значением nil:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2]
c = [:c0, :c1]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]

Если какой-либо массив в other_arrays больше, чем self, его хвостовые элементы игнорируются:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3, :b4]
c = [:c0, :c1, :c2, :c3, :c4, :c5]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]

Если задан блок, вызывается блок с каждым из подмассивов (сформированных как описано выше); возвращает nil

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
a.zip(b, c) {|sub_array| p sub_array} # => nil

Вывод:

[:a0, :b0, :c0]
[:a1, :b1, :c1]
[:a2, :b2, :c2]
[:a3, :b3, :c3]
array | other_array → new_array Показать исходный код
static VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
    VALUE hash, ary3;

    ary2 = to_ary(ary2);
    if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
        ary3 = rb_ary_new();
        rb_ary_union(ary3, ary1);
        rb_ary_union(ary3, ary2);
        return ary3;
    }

    hash = ary_make_hash(ary1);
    rb_ary_union_hash(hash, ary2);

    ary3 = rb_hash_values(hash);
    ary_recycle_hash(hash);
    return ary3;
}

Возвращает объединение array и массива other_array; дубликаты удаляются; порядок сохраняется; элементы сравниваются с использованием eql?:

[0, 1] | [2, 3] # => [0, 1, 2, 3]
[0, 1, 1] | [2, 2, 3] # => [0, 1, 2, 3]
[0, 1, 2] | [3, 2, 1, 0] # => [0, 1, 2, 3]

См. также: Array#union.

Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API