Поиск…


Синтаксис

  • a = [] # с использованием литерала массива
  • a = Array.new # эквивалентно использованию литерала
  • a = Array.new (5) # создать массив с 5 элементами со значением nil.
  • a = Array.new (5, 0) # создать массив с 5 элементами со значением по умолчанию 0.

#карта

#map , предоставляемый Enumerable, создает массив, вызывая блок для каждого элемента и собирая результаты:

[1, 2, 3].map { |i| i * 3 }
# => [3, 6, 9]

['1', '2', '3', '4', '5'].map { |i| i.to_i }
# => [1, 2, 3, 4, 5]

Исходный массив не изменяется; возвращается новый массив, содержащий преобразованные значения в том же порядке, что и исходные значения. map! может использоваться, если вы хотите изменить исходный массив.

В методе map вы можете вызывать метод или использовать proc для всех элементов массива.

# call to_i method on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&:to_i)
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# using proc (lambda) on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&->(i){ i.to_i * 2})
# => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

map является синонимом collect .

Создание массива с помощью конструктора literal []

Массивы могут быть созданы путем включения списка элементов в квадратных скобках ( [ и ] ). Элементы массива в этих обозначениях разделяются запятыми:

array = [1, 2, 3, 4]

Массивы могут содержать любые объекты в любой комбинации без ограничений по типу:

array = [1, 'b', nil, [3, 4]]

Создать массив строк

Массивы строк могут быть созданы с использованием синтаксиса строки ruby:

array = %w(one two three four)

Это функционально эквивалентно определению массива как:

array = ['one', 'two', 'three', 'four']

Вместо %w() вы можете использовать другие соответствующие пары разделителей: %w{...} , %w[...] или %w<...> .

Также возможно использовать произвольные не буквенно-цифровые разделители, такие как: %w!...! , %w#...# или %w@...@ .

%W можно использовать вместо %w для включения интерполяции строк. Рассмотрим следующее:

var = 'hello'

%w(#{var}) # => ["\#{var}"]
%W(#{var}) # => ["hello"]

Несколько слов можно интерпретировать, экранируя пространство с помощью \.

%w(Colorado California New\ York) # => ["Colorado", "California", "New York"]

Создать массив символов

2,0
array = %i(one two three four)

Создает массив [:one, :two, :three, :four] .

Вместо %i(...) вы можете использовать %i{...} или %i[...] или %i!...!

Кроме того, если вы хотите использовать интерполяцию, вы можете сделать это с помощью %I

2,0
a = 'hello'
b = 'goodbye'
array_one = %I(#{a} #{b} world)
array_two = %i(#{a} #{b} world)

Создает массивы: array_one = [:hello, :goodbye, :world] array_two = [:"\#{a}", :"\#{b}", :world] array_one = [:hello, :goodbye, :world] и array_two = [:"\#{a}", :"\#{b}", :world]

Создать массив с массивом :: new

Пустое Array ( [] ) может быть создано с помощью метода класса Array::new , Array::new :

Array.new    

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

Array.new 3 #=> [nil, nil, nil]

Существует два способа заполнения массива значениями по умолчанию:

  • Передайте неизменяемое значение в качестве второго аргумента.
  • Передайте блок, который получает текущий индекс и генерирует изменяемые значения.
Array.new 3, :x #=> [:x, :x, :x]

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

a = Array.new 3, "X"            # Not recommended.
a[1].replace "C"                # a => ["C", "C", "C"]

b = Array.new(3) { "X" }        # The recommended way.
b[1].replace "C"                # b => ["X", "C", "X"]

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

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

[1, 2, 3] << 4
# => [1, 2, 3, 4]

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

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

[1, 2, 3] << [4, 5]
# => [1, 2, 3, [4, 5]]

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

array = [1, 2, 3, 4]
array.pop
# => 4
array
# => [1, 2, 3]

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

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

array = [1,2,3,4,5,6]
array.delete_at(2) // delete from index 2
# => 3  
array 
# => [1,2,4,5,6] 


array = [1, 2, 2, 2, 3]
array - [2]
# => [1, 3]    # removed all the 2s
array - [2, 3, 4]
# => [1]       # the 4 did nothing

Объединение массивов:

[1, 2, 3] + [4, 5, 6]
# => [1, 2, 3, 4, 5, 6]

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

[1, 2, 3, 4, 5, 6] - [2, 3]
# => [1, 4, 5, 6]

[1, 2, 3] | [2, 3, 4]
# => [1, 2, 3, 4]

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

Вы также можете умножать массивы, например

[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]

Объединение массивов, пересечение и разность

x = [5, 5, 1, 3]
y = [5, 2, 4, 3]

Union ( | ) содержит элементы из обоих массивов с удаленными дубликатами:

x | y
=> [5, 1, 3, 2, 4]

Пересечение ( & ) содержит элементы, которые присутствуют как в первом, так и в втором массиве:

x & y
=> [5, 3]

Difference ( - ) содержит элементы, которые присутствуют в первом массиве и не присутствуют во втором массиве:

x - y
=> [1]

Фильтрация массивов

Часто мы хотим работать только с элементами массива, которые удовлетворяют конкретному условию:

Выбрать

Вернет элементы, соответствующие определенному условию

array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]

отклонять

Вернет элементы, которые не соответствуют определенному условию

array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]

Оба #select и #reject возвращают массив, поэтому они могут быть скованы:

array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 }.reject { |number| number < 5 }
  # => [5, 6]

Вставить, уменьшить

Ввод и сокращение - это разные имена для одного и того же. В других языках эти функции часто называют сгибами (например, foldl или foldr). Эти методы доступны для каждого объекта Enumerable.

Inject принимает две функции аргумента и применяет это ко всем парам элементов в массиве.

Для массива [1, 2, 3] мы можем добавить все это вместе со стартовым значением нуля, указав начальное значение и блокируем так:

[1,2,3].reduce(0) {|a,b| a + b} # => 6

Здесь мы передаем функцию начальное значение и блок, который говорит, чтобы добавить все значения вместе. Сначала блок запускается с 0 как a и 1 как b а затем принимает результат этого как следующий a поэтому мы добавляем 1 ко второму значению 2 . Затем мы берем результат этого ( 3 ) и добавляем к окончательному элементу в списке ( 3 ), давая нам наш результат ( 6 ).

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

[1,2,3].reduce {|a,b| a + b} # => 6

Кроме того, вместо передачи блока с помощью функции мы можем передать именованную функцию как символ либо с начальным значением, либо без него. При этом приведенный выше пример можно записать в виде:

[1,2,3].reduce(0, :+) # => 6

или опуская начальное значение:

[1,2,3].reduce(:+) # => 6

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

Вы можете получить доступ к элементам массива по их индексам. Нумерация индекса массива начинается с 0 .

%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'

Вы можете обрезать массив, используя диапазон

%w(a b c d)[1..2] # => ['b', 'c'] (indices from 1 to 2, including the 2)
%w(a b c d)[1...2] # => ['b'] (indices from 1 to 2, excluding the 2)

Это возвращает новый массив, но не влияет на оригинал. Ruby также поддерживает использование отрицательных индексов.

%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'

Вы также можете комбинировать отрицательные и положительные индексы

%w(a b c d e)[1...-1] # => ['b', 'c', 'd']

Другие полезные методы

first используйте для доступа к первому элементу массива:

[1, 2, 3, 4].first # => 1

Или first(n) для доступа к первым n элементам, возвращаемым в массиве:

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

Аналогично для last и last(n) :

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

Используйте sample для доступа к случайному элементу в массиве:

[1, 2, 3, 4].sample  # => 3
[1, 2, 3, 4].sample  # => 1

Или sample(n) :

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

Двумерный массив

Используя Array::new constructor, вы можете инициализировать массив с заданным размером и новым массивом в каждом из своих слотов. Внутренним массивам также может быть задан размер и начальное значение.

Например, для создания массива нулей 3x4:

array = Array.new(3) { Array.new(4) { 0 } }

Генерируемый массив выглядит так, когда печатается с помощью p :

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Вы можете читать или писать такие элементы:

x = array[0][1]
array[2][3] = 2

Массивы и оператор splat (*)

Оператор * можно использовать для распаковки переменных и массивов, чтобы они могли передаваться как отдельные аргументы методу.

Это можно использовать для обертывания одного объекта в массиве, если его еще нет:

def wrap_in_array(value)
  [*value]
end

wrap_in_array(1)
#> [1]

wrap_in_array([1, 2, 3])
#> [1, 2, 3]

wrap_in_array(nil)
#> []

В приведенном выше примере метод wrap_in_array принимает один аргумент, value .

Если value является Array , его элементы распаковываются и создается новый массив, содержащий этот элемент.

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

Если value равно nil , возвращается пустой массив.

Оператор splat особенно удобен при использовании в качестве аргумента в методах в некоторых случаях. Например, он позволяет обрабатывать nil , single values ​​и массивы согласованным образом:

def list(*values)
  values.each do |value|
    # do something with value
    puts value
  end
end

list(100)
#> 100

list([100, 200])
#> 100
#> 200

list(nil)
# nothing is outputted

декомпозиция

Любой массив может быть быстро разложен путем назначения его элементов в несколько переменных. Простой пример:

arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr

Предшествующая переменная с оператором splat ( * ) помещает в нее массив всех элементов, которые не были захвачены другими переменными. Если ни один не оставлен, будет назначен пустой массив. В одном назначении можно использовать только один знак:

a, *b = arr       # a = 1; b = [2, 3]
a, *b, c = arr    # a = 1; b = [2]; c = 3
a, b, c, *d = arr # a = 1; b = 2; c = 3; d = []
a, *b, *c = arr   # SyntaxError: unexpected *

Разложение безопасно и никогда не вызывает ошибок. nil s назначаются там, где недостаточно элементов, соответствующих поведению оператора [] при доступе к индексу за пределами границ:

arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil

Декомпозиция пытается вызвать to_ary неявно на назначаемый объект. Внедряя этот метод в свой тип, вы получаете возможность его разложить:

class Foo
  def to_ary
    [1, 2]
  end
end
a, b = Foo.new # a = 1; b = 2

Если разлагаемый объект не respond_to? to_ary , он рассматривается как одноэлементный массив:

1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil

Разложение также можно вложить с помощью выражения () -delimited decposition вместо того, что в противном случае было бы единственным элементом:

arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
#   ^^^^^

Это фактически противоположно splat .

Фактически любое выражение разложения может быть ограничено () . Но для первого уровня декомпозиция является необязательной.

a, b = [1, 2]
(a, b) = [1, 2] # the same thing

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

(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError

При присвоении литералу массива деструктурирующему выражению внешнее [] может быть опущено:

a, b = [1, 2]
a, b =  1, 2  # exactly the same

Это называется параллельным назначением , но оно использует ту же самую разложение под капотом. Это особенно удобно для обмена значениями переменных без использования дополнительных временных переменных:

t = a; a = b; b = t # an obvious way
a, b = b, a         # an idiomatic way
(a, b) = [b, a]     # ...and how it works

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

Поверните многомерный массив в одномерный (сплющенный) массив

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

Если у вас многомерный массив, и вам нужно сделать его простым (то есть одномерным) массивом, вы можете использовать метод #flatten .

Получить уникальные элементы массива

Если вам нужно прочитать элементы массива, избегающие повторений, вы используете метод #uniq :

a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]

Вместо этого, если вы хотите удалить все дублированные элементы из массива, вы можете использовать #uniq! метод:

a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]

В то время как результат тот же, #uniq! также сохраняет новый массив:

a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
a
#=> [1, 1, 2, 3, 4, 4, 5]

a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
a
#=> [1, 2, 3, 4, 5]

Получить все комбинации / перестановки массива

Метод permutation при вызове с блоком дает двумерный массив, состоящий из всех упорядоченных последовательностей набора чисел.

Если этот метод вызывается без блока, он вернет enumerator . Чтобы преобразовать в массив, вызовите метод to_a .

пример Результат
[1,2,3].permutation #<Enumerator: [1,2,3]:permutation
[1,2,3].permutation.to_a [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
[1,2,3].permutation(2).to_a [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
[1,2,3].permutation(4).to_a [] -> Нет перестановок длины 4

combination метод, с другой стороны, при вызове с блоком дает двумерный массив, состоящий из всех последовательностей набора чисел. В отличие от перестановки, порядок не учитывается в комбинациях. Например, [1,2,3] совпадает с [3,2,1]

пример Результат
[1,2,3].combination(1) #<Enumerator: [1,2,3]:combination
[1,2,3].combination(1).to_a [[1],[2],[3]]
[1,2,3].combination(3).to_a [[1,2,3]]
[1,2,3].combination(4).to_a [] -> Нет комбинаций длины 4

Вызов метода комбинации сам по себе приведет к перечислителю. Чтобы получить массив, вызовите метод to_a .

Методы repeated_combination и repeated_permutation аналогичны, за исключением того, что один и тот же элемент может повторяться несколько раз.

Например, последовательности [1,1] , [1,3,3,1] , [3,3,3] недействительны в регулярных комбинациях и перестановках.

пример # Combos
[1,2,3].combination(3).to_a.length 1
[1,2,3].repeated_combination(3).to_a.length 6
[1,2,3,4,5].combination(5).to_a.length 1
[1,2,3].repeated_combination(5).to_a.length 126

Создать массив последовательных чисел или букв

Это можно легко выполнить, вызвав Enumerable#to_a в объекте Range :

(1..10).to_a    #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

(a..b) означает, что он будет содержать все числа между a и b. Чтобы исключить последнее число, используйте a...b

a_range = 1...5
a_range.to_a       #=> [1, 2, 3, 4]

или же

('a'..'f').to_a    #=> ["a", "b", "c", "d", "e", "f"]
('a'...'f').to_a   #=> ["a", "b", "c", "d", "e"]

Удобный ярлык для создания массива - [*a..b]

[*1..10]           #=> [1,2,3,4,5,6,7,8,9,10]
[*'a'..'f']        #=> ["a", "b", "c", "d", "e", "f"]

Удалите все элементы nil из массива с #compact

Если массив имеет один или несколько элементов nil их необходимо удалить, Array#compact или Array#compact! методы могут использоваться, как показано ниже.

array = [ 1, nil, 'hello', nil, '5', 33]

array.compact # => [ 1, 'hello', '5', 33]

#notice that the method returns a new copy of the array with nil removed,
#without affecting the original

array = [ 1, nil, 'hello', nil, '5', 33]

#If you need the original array modified, you can either reassign it

array = array.compact # => [ 1, 'hello', '5', 33]

array = [ 1, 'hello', '5', 33]

#Or you can use the much more elegant 'bang' version of the method

array = [ 1, nil, 'hello', nil, '5', 33]

array.compact # => [ 1, 'hello', '5', 33]

array = [ 1, 'hello', '5', 33]

Наконец, обратите внимание, что если #compact или #compact! вызывается в массиве без элементов nil , они возвращают nil.

array = [ 'foo', 4, 'life']

array.compact # => nil

array.compact! # => nil

Создать массив чисел

Обычный способ создания массива чисел:

numbers = [1, 2, 3, 4, 5]

Объекты Range могут широко использоваться для создания массива чисел:

numbers = Array(1..10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

numbers = (1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

#step и #map позволяют налагать условия на диапазон чисел:

odd_numbers = (1..10).step(2).to_a # => [1, 3, 5, 7, 9]

even_numbers = 2.step(10, 2).to_a # => [2, 4, 6, 8, 10]

squared_numbers = (1..10).map { |number| number * number } # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Все вышеперечисленные методы загружают числа с нетерпением. Если вам нужно загрузить их лениво:

number_generator = (1..100).lazy # => #<Enumerator::Lazy: 1..100>

number_generator.first(10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Передача в массив из любого объекта

Чтобы получить массив из любого объекта, используйте Kernel#Array .

Ниже приведен пример:

Array('something') #=> ["something"]
Array([2, 1, 5])   #=> [2, 1, 5]
Array(1)           #=> [1]
Array(2..4)        #=> [2, 3, 4]
Array([])          #=> []
Array(nil)         #=> []

Например, вы можете заменить метод join_as_string из следующего кода

def join_as_string(arg)
  if arg.instance_of?(Array)
    arg.join(',')
  elsif arg.instance_of?(Range)
    arg.to_a.join(',')
  else
    arg.to_s
  end
end

join_as_string('something') #=> "something"
join_as_string([2, 1, 5])   #=> "2,1,5"
join_as_string(1)           #=> "1"
join_as_string(2..4)        #=> "2,3,4"
join_as_string([])          #=> ""
join_as_string(nil)         #=> ""

к следующему коду.

def join_as_string(arg)
  Array(arg).join(',')
end


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow