Реализация массивов в 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']