Массивы в Руби

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

Массивы(arrays) и хэши(hashes) в Ruby

Массивы (arrays) в Ruby — набор проиндексированных элементов. Индексация начинается с нуля [0].
Ассоциативных массивов в Ruby нет.
Хэши(hashes) в Ruby — набор элементов в виде [ключ] => «значение»

Как видно на картинке, массивы и хэши очень похожи, основные различия между ними:
1) ключ в хэше вы выбираете сами, а в массиве ключом является индекс
2) вытекает из первого — элементы хэша не отсортированы в отличие от массивов

Как в массивах не может быть двух элементов с одинаковым индексом, так и в хэше не может быть двух элементов с одинаковым ключом.

Массивы

Примеры из жизни

Приведу несколько примеров, чтобы продемонстрировать приемы работы

#В массиве с именами, сделать все первые буквы заглавными
arr = ['ivan','petr','Denis','Dima']
arr.map!{ |e| e.capitalize } # => ['Ivan','Petr','Denis','Dima']

#Найти элементы массива значения которых содержат email
arr = ['peter','jons','barbara','Susan', 'ya@yandex.ru', 'person.name@gmail.com']
arr.grep(/^[\w\d][\w.]{1,15}@[\w]{2,8}.[\w]{2,5}/) # => ['ya@yandex.ru', 'person.name@gmail.com']

#Проверить, содержит ли массив определенный элемент 
arr = ['one','two','three']
arr.include? "two" # => true

#Добавить элемент в массив
arr = ['one','two','three']
arr << 'four' # => ['one','two','three','four']

#Удалить элемент с заданным значением из массива
arr = ['one','two','three']   
arr.delete('one') # => ['two','three']

Факты о Ruby массивах

 

  • Массивы в Ruby динамичные. Это значит что можно задавать размер массива при его создании и что массив растёт по мере добавления в него элементов без вмешательства программиста
    arr = Array.new(3) # => [nil,nil,nil]
    arr << 'some string' # => [nil,nil,nil,'some string']
  • Массивы в Ruby гетерогенные, т.е. могут хранить данные разных типов
    arr = [1,'string',['another','array'],{'hash'=>'inside'},MyClass.new] 
    #при включении в массив объекта, он хранит только ссылку на объект
  • Массивы содержат информацию о своём размере, т.о. не нужно тратить компьютерную мощь на его определение

 

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

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

#Создание массивов
arr = [1,2,3,4]   # создание массива [1,2,3,4]
arr = Array.new  # инициализация пустого массива
arr = Array.new(3)  # создание массива с 3-мя пустыми элементами [nil,nil,nil]
arr = Array.new(3) {'text'} # создание массива с 3-мя элементами 'text' ['text','text','text']

#Получение элементов массива, присвоение значений, операции с массивами
arr = [1,2,3,4,5]
arr[0]       # => 1 - получить значение первого элемента массива
arr[1] = 3  # => [1,3,3,4,5] - присвоить элементу с индексом [1] - значение 3
arr[7] = 8  # => [1,2,3,4,5,nil,nil,8] - присвоить элементу с индексом [7] - значение 8
arr[-2]      # => 4 - получить значение второго элемент с конца
arr[9]       # => nil - элемент с индексом девять не содержит значения
arr[2,2]     # => [3,4] - получить значение 2-х элементов начиная с индекса [2]
arr[2..4]    # => [3,4,5] - получить значения элементов с индексом от [2] до [4] включительно
arr[2...4]   # => [2,3] - получить значения элементов с индексом от [2] до [4] не включая последний элемент
arr.values_at(0,1,4) # => [1,2,5] - получить значения элементов с перечисленными индексами
arr.uniq    # - удалить повторяющиеся элементы в массиве
arr.sort_by {rand} # => [2,3,1,4,5] - отсортировать массив в случайном порядке
arr << 6 # => [1,2,3,4,5,6] - добавляет элемент с указанным значением в массив
arr.reverse # => [5,4,3,2,1] - отсортировать в обратном порядке

#Нахождение размеров массива 
arr = [1,2,nil,nil,3,4]
arr.size    # => 6
arr.length # => 6
arr.nitims # => 4 - размер массива не считая пустых элементов

#Выбор элементов массива на основе критерия
arr = [1,2,3,4,5,5,55,'six','seven']
arr.detect {|e| e == 5} # => [5] - возвращает ПЕРВЫЙ найденный элемент
arr.find_all{|e| e == 5} # => [5,5] - возвращает ВСЕ найденные элементы
arr.grep(/sev/) # => [seven] - возвращает элементы, значения которых совпадают с рег. выражением
arr.reject {|e| e == 5} # => [1,2,3,4,55,'six','seven'] - УДАЛЯЕТ элементы из массива
arr.min   #  - возвращает минимальное значение массива 
arr.max  #  - возвращает максимальное значение массива
arr.index 'seven'  # => 8 - получить индекс  ПЕРВОГО элемента со значением 'seven'
arr.include? 1 # => true - проверить, содержит ли массив указанные элемент

#Операции между массивами 
a = [1,2,3,4,5]
b = [3,4,5,6,7]
a | b # => [1,2,3,4,5,6,7] - объеденить массивы с удалением повторяющихся элементов
a & b # => [3,4,5] - сформировать массив содержащий общие элементы обоих массивов
a + b # => [1,2,3,4,5,3,4,5,6,7] - объеденить массивы без удаления повторяющихся элементов 
a - b  # => [1,2] - удалить из массива a элементы совпадающие с содержащимися в массиве b

#Удаление элементов массива
arr = [1,2,3,4,5,'six','seven']
arr.delete_at(3) # => [1,2,3,5] - удаляет элемент с индексом [3] из массива и возвращает значение удаленного элемента или nil, если элемент не найден
arr.delete('six') # => [1,2,3,4,5,'seven'] - удалить элемент со значением 'six' и вернуть значение удаленного элемента
arr.pop # => [1,2,3,4,5,'six'] - как и следует из названия, удаляет задний(последний) элемент
arr.shift # => [2,3,4,5,'six','seven'] - удаляет первый элемент массива
arr.clear # => [] - очищает массив

#Поочередная обработка элементов массива
arr = [1,2,3,4,5]
arr2 = []
arr.reverse_each { |e| arr2 << e+1 } # => arr2 = [6,5,4,3,2] - обрабатывает элементы в обратном порядке

arr.each_with_index do |value,index| 
  puts "index #{index} and value #{value}"    # передает в блок значение и индекс 
end

# Преобразование массива в строку
arr = [1,2,3,4]
arr.join(' and ') # => "1 and 2 and 3 and 4"
list[0..-2].join(", ") + ", and " + list[-1]

#Хитрый трюк
a = [1,2,3,4]
b = ['a','b','c','d']
c = a.zip(b) # => [[1,'a'], [2,'b'], [3,'c'], [4,'d']]
d = c.flatten # => [1,'a',2,'b',3,'c',4,'d']

    

Оставьте комментарий