Работа с массивами в Ruby

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

В Ruby массивы могут содержать любые типы данных, включая числа, строки и другие объекты Ruby.

Давайте рассмотрим простой пример массива. Предположим, вам нужно вести список адресов электронной почты. Без помощи массива вы можете хранить адреса электронной почты в переменных в файле emails.rb, например, так:

email1 = "ceo@example.com"
email2 = "admin@example.com"
email3 = "support@example.com"
email4 = "sales@example.com"

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

Массив значительно облегчает работу:

emails = [
"ceo@example.com",
"admin@example.com",
"support@example.com",
"sales@example.com"
]

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

Чтобы получить доступ к конкретному элементу массива, можно сослаться на него по индексу, который обозначает его позицию в массиве. В Ruby индексация начинается с 0. То есть, чтобы извлечь первый элемент массива emails, нужно указать индекс 0 в квадратных скобках рядом с переменной:

print emails[0];
ceo@example.com

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

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

Чтобы создать массив в Ruby, используйте квадратные скобки [] и разделите значения массива запятыми.

Для примера попробуйте создать массив с названиями цветов в файле colours.rb и присвоить его переменной, например:

colours = ["Blue", "White", "Pale Green"]

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

print colours
["Blue", "White", "Pale Green"]

Чтобы создать массив, в котором каждый элемент выражается одним словом, используйте синтаксис %w{}. Он создает массив слов:

days = %w{Monday Tuesday Wednesday Thursday Friday Saturday Sunday}

Этот массив аналогичен такому массиву:

days =  ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

Обратите внимание: метод %w{} позволяет опустить кавычки и запятые между элементами.

Массивы часто используются для группировки списков похожих типов данных, но в Ruby массивы могут содержать любое значение или сочетание значений, включая и другие массивы. Ниже приведен пример массива, который содержит строку, значение nil, целое число и массив строк:

record = [
"8host",
null,
7,
[
"another",
"array",
]
]

Доступ к значениям массива

Чтобы получить доступ к элементу в массиве Ruby, нужно сослаться на индекс элемента в квадратных скобках.

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

sharks = ["Hammerhead", "Great White", "Tiger"]

Массив sharks состоит из 3 элементов. Каждый элемент имеет такой индекс:

Hammerhead Greate White Tiger
0 1 2

Первым элементом массива является Hammerhead, он индексируется как 0. Последний элемент — Tiger, он индексируется как 2. Индексация начинается с 0, а не с 1, об этом очень важно помнить.

Примечание: Чтобы быстрее запомнить, как правильно индексировать элементы массива, попробуйте воспринимать индекс элемента как сдвиг от начала массива. Например, первый элемент сдвигается от начала на 0 позиций, второй – на 1, третий – на 2, и т. д.

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

sharks.length
3

Метод length выдает не индекс последнего элемента (тогда было бы 2), а общее количество элементов в массиве – их 3.

Чтобы узнать индекс определенного элемента в массиве, используйте метод index():

print sharks.index("Tiger")
2

Этот метод возвращает индекс первого элемента, который совпал с запрашиваемым текстом. Если номер индекса не найден (например, если такого значения не существует), консоль вернет nil.

print sharks.index("Whale")
nil

Чтобы найти последний элемент в массиве, используйте индекс -1:

print sharks[-1]
"Tiger"

Также Ruby предоставляет методы first и last, которые выводят первый и последний элемент массива без индекса.

puts sharks.first
puts sharks.last
"Hammerhead"
"Tiger"

При запросе несуществующего индекса программа выдаст nil.

sharks[10]
nil

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

nested_array = [
[
"salmon",
"halibut",
],
[
"coral",
"reef",
]
]

Чтобы получить доступ к элементам во вложенном массиве, нужно добавить номер индекса, соответствующий внутреннему массиву. Например, чтобы извлечь из этого вложенного массива значение coral, можно использовать следующий оператор:

print nested_array[1][0];
coral

Сначала указывается индекс переменной nested_array (это 1), что выдает массив [«coral», «reef»]. После этого указывается индекс элемента во вложенном массиве (это 0).

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

В массиве sharks сейчас 3 элемента, которые индексируются от 0 до 2.

Добавить в массив новый элемент можно несколькими способами. Можно присвоить значение следующему индексу (в этом случае это 3):

sharks[3] = "whale";
print sharks
["Hammerhead", "Great White", "Tiger", "Whale"]

Однако этот метод может стать причиной ошибок. Если вы добавите элемент и случайно пропустите один индекс, это создаст в массиве элемент nil.

sharks[5] = "Sand";
print sharks;
["Hammerhead", "Great White", "Tiger", "Whale", nil, "Sand"]

При запросе элемента с индексом 4 вы получите значение nil:

sharks[4]
nil

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

sharks.push("thresher")
print sharks
["Hammerhead", "Great White", "Tiger", "Whale", nil, "Whale", "Thresher"]

Также можно использовать синтаксис << вместо метода push, чтобы добавить элемент в конец массива:

sharks << «Bullhead»

[«Hammerhead», «Great White», «Tiger», «Whale», nil, «Whale», «Thresher», «Bullhead»]

Добавить элемент в начало массива можно с помощью метода unshift().

sharks.unshift("Angel")
print sharks
["Angel", "Hammerhead", "Great White", "Tiger", "Whale", nil, "Whale", "Thresher", "Bullhead"]

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

Чтобы удалить определенный элемент из массива, используйте методы delete или delete_at. Ранее в массиве sharks мы случайно создали элемент nil. Давайте удалим его.

print sharks.index(nil)
4

Метод delete_at позволяет удалять элемент по индексу:

sharks.delete_at(4)
print sharks
["Angel", "Hammerhead", "Great White", "Tiger", "Whale", "Thresher", "Bullhead"]

Метод delete удаляет из массива элементы, которые соответствуют заданному вами значению. Например, попробуйте удалить с его помощью элемент Whale:

sharks.delete("Whale")
print sharks;
["Angel", "Hammerhead", "Great White", "Tiger", "Thresher", "Bullhead"]

Метод delete удаляет все вхождения заданного значения, поэтому если в массиве есть повторяющиеся элементы, все они будут удалены.

Метод pop удаляет последний элемент в массиве.

sharks.pop
print sharks;
["Angel", "Hammerhead", "Great White", "Tiger", "Thresher"]

Элемент Bullhead был удален, поскольку это последний элемент массива. Чтобы удалить первый элемент массива, используйте метод shift.

sharks.shift
print sharks
["Hammerhead", "Great White", "Tiger", "Thresher"]

Теперь из массива был удален элемент Angel.

С помощью методов pop и shift можно удалять элементы из начала и конца массивов. По возможности рекомендуется использовать метод pop, так как при этом остальные элементы массива сохраняют свои исходные индексы.

Методы delete_at, pop и shift меняют исходный массив и выводят элемент, который вы удалили. Рассмотрите этот пример:

sharks = ["Hammerhead", "Great White", "Tiger", "Whale"]
deleted_at_element = sharks.delete_at(1)
popped_element = sharks.pop
puts "Deleted_at element: #{deleted_at_element}"
puts "Popped element: #{popped_element}"
puts "Remaining array: #{sharks}"
Deleted_at element: Great White
Popped element: Whale
Remaining array: ["Hammerhead", "Tiger"]

Теперь вы знаете несколько методов удаления элемента из массива.

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

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

Первым элементом массива sharks является Hammerhead. Замените «Hammerhead» на «Angel»:

sharks = ["Hammerhead", "Great White", "Tiger", "Whale"]
sharks[0] = "Angel"
print sharks;
["Angel", "Great White", "Tiger", "Whale"]

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

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

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

Ruby предоставляет синтаксис for..in, который выглядит так:

sharks = ["Hammerhead", "Great White", "Tiger", "Whale"]
for shark in sharks do
puts shark
end

Вот как это работает. Ruby присваивает каждый элемент массива локальной переменной shark. Затем можно вывести значение элемента с помощью puts.

Метод for..in используется не очень часто. Массивы Ruby являются объектами, и они предоставляют метод each  для работы с элементами. Метод each  работает так же, как и for..in, но имеет другой синтаксис:

sharks = ["Hammerhead", "Great White", "Tiger", "Whale"]
sharks.each do |shark|
puts shark
end

Метод each использует синтаксис, который часто применяется в программировании в Ruby. В качестве аргумента требуется блок Ruby. Блок – это некоторый код, который будет выполнен в контексте метода. В этом случае это puts shark. Ключевое слово shark в символах | является локальной переменной, она представляет элемент в массиве, к которому будет обращаться блок. Ruby присваивает элемент этой переменной и выполняет код в блоке. Метод each повторяет этот процесс для каждого элемента массива. Результат выглядит следующим образом:

Hammerhead
Great White
Tiger
Whale

Когда блок выражен всего одной строкой, разработчики Ruby заменяют слова do и end фигурными скобками и уплотняют весь оператор в одну строку, например:

...
sharks.each {|shark| puts shark }

Это дает те же результаты, но код становится меньше.

Метод each_with_index работает аналогичным образом, но также дает доступ к индексу элемента массива. Программа может использовать each_with_index для отображения индекса и значения каждого элемента:

sharks = ["Hammerhead", "Great White", "Tiger", "Whale"]
sharks.each_with_index do |shark, index|
puts "The index is #{index}"
puts "The value is #{shark}"
end

Ruby присваивает каждый элемент массива переменной shark, а индекс элемента – переменной index . Затем можно сослаться на обе переменные в блоке.

The index is 0
The value is Hammerhead
The index is 1
The value is Great White
The index is 2
The value is Tiger
The index is 3
The value is Whale

При разработке программ часто нужно взаимодействовать с элементами в массиве (например, чтобы отобразить элементы из базы данных на веб-сайте или прочитать строки из файла и обработать эти данные).

Заключение

Массивы – универсальная и очень важная часть программирования в Ruby. В этом мануале вы научились создавать массивы и получать доступ к отдельным элементам, а также добавлять, изменять и удалять элементы в массиве. Кроме того, теперь вы умеете выполнять итерацию массива для отображения данных.

Читайте также:

Tags: