Spec-Zone.ru › Ruby 3.1

класс Array

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

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

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

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

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

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

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

  • …

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

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

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

  • …

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

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

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

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

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

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

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

Вы можете создать объект массива явно с помощью:

  • Литерала массива.

Вы можете преобразовать определённые объекты в массивы с помощью:

  • Метода Array.

Массив может содержать различные типы объектов. Например, массив ниже содержит 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]

Получение информации о массиве

Массивы отслеживают свою длину в любое время. Чтобы узнать количество элементов в массиве, используйте 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]

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

Метод 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, который определяет, какие элементы должны быть обработаны и как. В случае Array’s 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]

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

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

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

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]

Что здесь

Сначала, что находится где-то ещё. Класс Array:

  • Наследуется от класса Object.

  • Включает модуль Enumerable, который предоставляет десятки дополнительных методов.

Здесь класс Array предоставляет методы, которые полезны для:

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

  • Запросы

  • Сравнение

  • Получение

  • Назначение

  • Удаление

  • Объединение

  • Итерация

  • Преобразование

  • И ещё многое другое…

Методы создания массива

::[]

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

::new

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

::try_convert

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

Методы запроса

END_OF_DOCUMENT_MARKER
length, size

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

include?

Возвращает значение, указывающее, содержит ли массив какой-либо элемент, == заданный объект.

empty?

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

all?

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

any?

Возвращает значение, указывающее, удовлетворяет ли какой-либо элемент заданному критерию.

none?

Возвращает значение, указывающее, не содержит ли массив ни одного элемента, == заданный объект.

one?

Возвращает значение, указывающее, содержит ли массив ровно один элемент, == заданный объект.

count

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

find_index, index

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

rindex

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

hash

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

Методы для сравнения

#<=>

Возвращает -1, 0 или 1 в зависимости от того, self меньше, равно или больше заданного объекта.

#==

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

eql?

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

Методы для извлечения

Эти методы не изменяют self.

[]

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

fetch

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

first

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

last

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

max

Возвращает один или несколько элементов с максимальным значением, определённым по <=> или заданному блоку.

max

Возвращает один или несколько элементов с минимальным значением, определённым по <=> или заданному блоку.

minmax

Возвращает элементы с минимальным и максимальным значением, определённым по <=> или заданному блоку.

assoc

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

rassoc

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

at

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

values_at

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

dig

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

drop

Возвращает конечные элементы, определённые заданным индексом.

take

Возвращает начальные элементы, определённые заданным индексом.

drop_while

Возвращает конечные элементы, определённые заданным блоком.

take_while

Возвращает начальные элементы, определённые заданным блоком.

slice

Возвращает последовательные элементы, определённые заданным аргументом.

sort

Возвращает все элементы в порядке, определённом по <=> или заданному блоку.

reverse

Возвращает все элементы в обратном порядке.

compact

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

select, filter

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

uniq

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

rotate

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

bsearch

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

bsearch_index

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

sample

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

shuffle

Возвращает элементы в случайном порядке.

Методы для присвоения

Эти методы добавляют, заменяют или переупорядочивают элементы в self.

[]=

Присваивает указанные элементы заданному объекту.

push, append, <<

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

unshift, prepend

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

insert

Вставляет заданные объекты по заданному смещению; не заменяет элементы.

concat

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

fill

Заменяет указанные элементы заданными объектами.

replace

Заменяет содержимое self содержимым заданного массива.

reverse!

Заменяет self своими элементами в обратном порядке.

rotate!

Заменяет self своими элементами, сдвинутыми.

shuffle!

Заменяет self своими элементами в случайном порядке.

sort!

Заменяет self своими отсортированными элементами, определёнными по <=> или заданному блоку.

sort_by!

Заменяет self своими элементами, отсортированными по заданному блоку.

Методы для удаления

Каждый из этих методов удаляет элементы из self:

pop

Удаляет и возвращает последний элемент.

shift

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

compact!

Удаляет все не-nil элементы.

delete

Удаляет элементы, равные заданному объекту.

delete_at

Удаляет элемент по заданному смещению.

delete_if

Удаляет элементы, указанные заданным блоком.

keep_if

Удаляет элементы, не указанные заданным блоком.

reject!

Удаляет элементы, указанные заданным блоком.

select!, filter!

Удаляет элементы, не указанные заданным блоком.

slice!

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

uniq!

Удаляет дубликаты.

Методы для объединения

#&

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

intersection

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

+

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

-

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

#|

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

union

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

difference

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

product

Возвращает или выводит все комбинации элементов из self и переданных массивов.

Методы для итерации

each

Передает каждый элемент в заданный блок.

reverse_each

Передает каждый элемент в обратном порядке в заданный блок.

each_index

Передает индекс каждого элемента в заданный блок.

cycle

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

combination

Вызывает заданный блок с комбинациями элементов self; комбинация не использует один и тот же элемент более одного раза.

permutation

Вызывает заданный блок с перестановками элементов self; перестановка не использует один и тот же элемент более одного раза.

repeated_combination

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

repeated_permutation

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

Методы для преобразования

map, collect

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

map!, collect!

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

flatten

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

flatten!

Заменяет каждый вложенный массив в self элементами из этого массива.

inspect, to_s

Возвращает новый String, содержащий элементы.

join

Возвращает новую строку, содержащую элементы, соединённые с помощью разделителя.

to_a

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

to_ary

Возвращает self.

to_h

Возвращает новый хэш, сформированный из элементов.

transpose

Транспонирует self, который должен быть массивом массивов.

zip

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

Другие методы

*

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

  • С целочисленным аргументом n, новый массив, являющийся конкатенацией n копий self.

  • Со строковым аргументом field_separator, новую строку, эквивалентную join(field_separator).

abbrev

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

pack

Упаковывает элементы в двоичную последовательность.

sum

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

for 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 не возвращает объект массива.

END_OF_DOCUMENT_MARKER

Методы открытого экземпляра

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);
    if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }
    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, или 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 или 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 или nil Показать исходный код
array[start, length] → object или nil
array[range] → object или nil
array[aseq] → object или 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 + length и 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 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?

append(*args)

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

Добавляет каждый аргумент в 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 или 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, выбранный с помощью двоичного поиска.

См. Двоичный поиск.

bsearch_index {|element| ... } → integer или 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 (!RTEST(v)) {
            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 # => []
collect -> new_enumerator Показать исходный код
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
END_OF_DOCUMENT_MARKER
collect! -> new_enumerator Показать исходный код
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;
}

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

Если задан блок и целочисленный аргумент 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;
}

Добавляет к массиву все элементы из каждого массива в списке 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, возвращает количество элементов от == до obj:

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

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

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

С аргументом obj и заданным блоком, выводит предупреждение, игнорирует блок и возвращает количество элементов от == до 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 (NIL_P(result)) result = rb_ary_new();
    return result;
}

Возвращает новый массив, содержащий все элементы массива self за исключением первых n элементов, где 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 Show source
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 Show source
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 Show source
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 Show source
static VALUE
rb_ary_empty_p(VALUE ary)
{
    return RBOOL(RARRAY_LEN(ary) == 0);
}

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

eql? other_array → true or false Show source
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 Show source
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.

С единственным аргументом Integer 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 Show source
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 и Integer 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, Integer start, и Integer 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 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 до конца; заменяет соответствующий элемент возвращаемым значением блока:

Если начало находится в диапазоне (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 <= -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:

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

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

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"]
filter()

Вызывает блок, если он задан, с каждым элементом 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
filter!()

Вызывает блок, если он задан, с каждым элементом 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!
find_index -> new_enumerator Показать исходный код
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 → объект или nil Показать исходный код
first(n) → новый_массив
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 → новый_массив Показать исходный код
flatten(level) → новый_массив
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 или nil Показать исходный код
flatten!(level) → self или 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
hash → целое число Показать исходный код
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 или false Показать исходный код
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(объект) → целое число или nil
index {|элемент| ... } → целое число или nil
index → новый_перечислитель

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

Если аргумент 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
initialize_copy(other_array) -> self Показать исходный код
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 Показать исходный код
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 → новая_строка Показать исходный код
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
intersect?(other_ary) → true или false Показать исходный код
static VALUE
rb_ary_intersect_p(VALUE ary1, VALUE ary2)
{
    VALUE hash, v, result, shorter, longer;
    st_data_t vv;
    long i;

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

    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)) return Qtrue;
        }
        return Qfalse;
    }

    shorter = ary1;
    longer = ary2;
    if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
        longer = ary1;
        shorter = ary2;
    }

    hash = ary_make_hash(shorter);
    result = Qfalse;

    for (i=0; i<RARRAY_LEN(longer); i++) {
        v = RARRAY_AREF(longer, i);
        vv = (st_data_t)v;
        if (rb_hash_stlike_lookup(hash, vv, 0)) {
            result = Qtrue;
            break;
        }
    }
    ary_recycle_hash(hash);

    return result;
}

Возвращает true , если массив и other_ary имеют хотя бы один общий элемент, в противном случае возвращает false.

a = [ 1, 2, 3 ]
b = [ 3, 4, 5 ]
c = [ 5, 6, 7 ]
a.intersect?(b)   #=> true
a.intersect?(c)   #=> false
END_OF_DOCUMENT_MARKER
intersection(*other_arrays) → new_array Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 → element Показать исходный код
max {|a, b| ... } → element
max(n) → new_array
max(n) {|a, b| ... } → new_array
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, 0]

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

С блоком и без аргумента вызывает блок 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 → element Показать исходный код
min { |a, b| ... } → element
min(n) → new_array
min(n) { |a, b| ... } → new_array
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]

Если задан блок, он должен возвращать Integer.

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

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

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

['0', '00', '000'].min(2) {|a, b| a.size <=> b.size } # => ["0", "00"]
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 143
def pack(fmt, buffer: nil)
  Primitive.pack_pack(fmt, buffer)
end

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

# packed data is appended by default
[255].pack("C", buffer:"foo".b) #=> "foo\xFF"

# "@0" (offset 0) specifies that packed data is filled from beginning.
# Also, original data after packed data is removed. ("oo" is removed.)
[255].pack("@0C", buffer:"foo".b) #=> "\xFF"

# If the offset is bigger than the original length, \x00 is filled.
[255].pack("@5C", buffer:"foo".b) #=> "foo\x00\x00\xFF"

Обратите внимание, что опция «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 the same as "n"
J> j> J!> j!> |         | "L>" is the 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 the same as "v"
J< j< J!< j!< |         | "L<" is the 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 → объект или nil Показать исходный код
pop(n) → новый_массив
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.

prepend(*args)

Добавляет заданные 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 Показать исходный код
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]]

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

Без аргументов возвращает массив из 1-элементных массивов, каждый из которых содержит элемент из 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 как 1-элементный массив:

a.product {|combination| p combination }

Вывод:

[0]
[1]
[2]
push(*objects) → self Показать исходный код
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
END_OF_DOCUMENT_MARKER
rassoc(obj) → found_array or nil Показать исходный код
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 Показать исходный код
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]

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

a = [:foo, 'bar', 2]
a.reject # => #<Enumerator: [:foo, "bar", 2]:reject>
reject! {|element| ... } → self or nil Показать исходный код
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 если элементы не были удалены.

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

a = [:foo, 'bar', 2]
a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
repeated_combination(n) {|combination| ... } → self Показать исходный код
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' }

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

a = [0, 1, 2]
a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>

Используя Enumerator, удобно показать комбинации и их количества для некоторых значений 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 Показать исходный код
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' }

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

a = [0, 1, 2]
a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>

Используя Enumerator, удобно показать перестановки и их количества для некоторых значений 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 Показать исходный код
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 Показать исходный код
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 в качестве значения count:

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 в качестве значения count:

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 60
def sample(n = (ary = false), random: Random)
  if Primitive.mandatory_only?
    # Primitive.cexpr! %{ rb_ary_sample(self, rb_cRandom, Qfalse, Qfalse) }
    Primitive.ary_sample0
  else
    # Primitive.cexpr! %{ rb_ary_sample(self, random, n, ary) }
    Primitive.ary_sample(random, n, ary)
  end
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]

Аргумент n должен быть неотрицательным числовым значением. Порядок в результирующем массиве не связан с порядком в self. Возвращает новый пустой массив, если 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]

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

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, если элементы не были удалены.

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

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]
size()

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

Псевдоним для: length
slice(index) → object or nil
slice(start, length) → object or nil
slice(range) → object or nil
slice(aseq) → object or 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) → object or nil Показать исходный код
slice!(start, length) → new_array or nil
slice!(range) → new_array or 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 → new_array Показать исходный код
sort {|a, b| ... } → new_array
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.receiver = ary;
        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! → new_enumerator
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_BIGNUM_TYPE_P(e))
            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_BIGNUM_TYPE_P(e))
                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 возвращает init + e1 + e2 + e3.

Примеры:

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));
}

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

При использовании блока, блок вызывается для каждого последующего элемента массива; выполнение останавливается, если блок возвращает ложное значение или 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"}
to_s()

Возвращает новую строку, сформированную путём вызова метода #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;
}

Возвращает новый массив, являющийся объединением исходного массива и всех переданных массивов; дубликаты удаляются; порядок сохраняется; элементы сравниваются с помощью 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]

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

Связанно с: 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;
}

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

Без блока, дубликаты определяются и удаляются с помощью метода 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;
}

Удаляет дублирующие элементы из массива; сохраняется первое вхождение; возвращает массив, если элементы были удалены; иначе возвращает nil.

Без блока, элементы определяются и удаляются с помощью метода eql? для сравнения.

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

a = [0, 0, 1, 1, 2, 2]
a.uniq! # => [0, 1, 2]

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

С блоком, блок вызывается для каждого элемента; дубликаты определяются (с помощью метода eql?) и удаляются, то есть элементы, для которых блок возвращает одинаковое значение.

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

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;
}

Добавляет указанные элементы в начало массива:

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;
}

Возвращает новый массив, элементами которого являются элементы исходного массива по заданным индексам (целые числа или диапазоны):

Для каждого положительного индекса возвращается элемент по этому смещению:

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

Заданные индексы могут быть в любом порядке и повторяться:

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

Присваивает nil для индекса, выходящего за пределы массива:

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

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

Для каждого отрицательного индекса отсчёт ведётся от конца массива:

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

Присваивает nil для индекса, выходящего за пределы массива:

a = [:foo, 'bar', 2]
a.values_at(0, -5, 1, -6, 2) # => [:foo, nil, "bar", nil, 2]

Заданные индексы могут содержать смесь знаков:

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-ый элемент исходного массива.

  • n-ый элемент каждого из переданных массивов.

Если все массивы имеют одинаковый размер:

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

Если любой массив в списке короче исходного массива, заполняется 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]]

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

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–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API