Ruby: различия между версиями

Содержимое удалено Содержимое добавлено
Нет описания правки
Строка 511:
 
== Подробнее о массивах ==
 
 
=== Способы создания массива ===
=== Диапазоны ===
У диапахонов есть очень полезное свойство: наличие метода to_a. Это значит, что любой диапазон значений можно с легкостью превратить в массив. Этот массив будет содержать все элементы, которые входят в данный диапазон.
 
(1..10).to_a #-> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
('a'..'d').to_a #-> ['a', 'b', 'c', 'd']
 
Раз уж речь зашла о диапазонах, то давайте посмотрим, как они позволяют получать подмассивы. И насколько изящно у них это получается. Рассмотрим массив:
 
[ 'a', 'b', 'c', 'd', 'e']
 
Всем нам известно, как нумеруются элементы массива: нумерация начинается с нуля и далее по возрастающей.
 
[ 'a'<math>{}^{0}</math>, 'b'<math>{}^{1}</math>, 'c'<math>{}^{2}</math>, 'd'<math>{}^{3}</math>, 'e'<math>{}^{4}</math> ]
 
Такая нумерация называется в Ruby "положительной индексацией". Хм, &mdash; скажете вы, &mdash; а есть еще и "отрицательная"? Да, есть!
 
[ 'a'<math>{}^{+0}_{-5}</math>, 'b'<math>{}^{+1}_{-4}</math>, 'c'<math>{}^{+2}_{-3}</math>, 'd'<math>{}^{+3}_{-2}</math>, 'e'<math>{}^{+4}_{-1}</math> ]
 
Кстати, плюсы поставлены для красоты. И без них все будет работать. Но вернемся к отрицательной индексации. Какой ее смысл? Для того, чтобы его пояснить, давайте решим задачку: дан массив, необходимо получить предпоследний элемент.
 
maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ maccuB.size - 2 ]
 
В данном случае, мы использовали метод .size, который возвращает размер массива. Разработчики языка Ruby заметили, что вызов maccuB.size приходится писать с завидной регулярностью. И решили от него избавиться. И получилось вот что:
 
maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ -2 ] #-> 'd'
 
Индекс -2 имеет смысл: "предпоследний элемент массива". Вот так и появилась отрицательная индексация. Теперь давайте разберемся с диапазонами. Оказывается в них тоже можно использовать отрицательную индексацию. На этот раз решим другую задачку: необходимо получить все элементы массива, кроме первого и последнего. Вот как она решается:
 
maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ 1..-2 ] #-> ['b', 'c', 'd']
или
 
maccuB = [ 'a', 'b', 'c', 'd', 'e']
puts maccuB[ 1...-1 ] #-> ['b', 'c', 'd']
 
Второй вариант с тремя точками, что автоматически приближает правую границу диапазона на одну позицию влево.
 
=== Методы работы с массивами ===
 
Разнообразие и полезность методов у массивов создает иллюзию у программистов, что все сложные алгоритмы уже реализованы в виде методов. Это не так, но в руках у программистов Ruby находится действительно обширная библиотека методов. Здесь мы не будем рассматривать все методы. Рассмотрим лишь самые употребляемые.
 
==== Поиск максимального/минимального элемента ====
 
Вспомните сколько усилий вам приходилось прилагать, чтобы найти максимальный элемент? А сколько раз вы повторяли этот кусок кода в своих программах? Ну а в Ruby поиск максимального элемента осуществляется при помощи метода .max, а в более сложных случаях при помощи метода .max_by (начиная с версии 1.9). Вот как это выглядит:
 
['y','nona','6bIJIa','co6aka'].max #-> 'y' максимальный по значению
['y','nona','6bIJIa','co6aka'].max_by{ |elem| elem.size } #-> '6bIJIa' максимальный по размеру строки
 
Методы .min и .min_by работают аналогично:
 
['y','nona','6bIJIa','co6aka'].min #-> '6bIJIa' минимальный по значению
['y','nona','6bIJIa','co6aka'].min_by{ |elem| elem.size } #-> 'y' максимальный по размеру строки
Результат получился с точностью до наоборот, но это случайность. Ну как? Сильно? Вот Ruby-программисты пользуются этими методами уже долгие года.
 
==== Сортировка по возрастанию ====
 
Не буду "травить душу" долгими байками. Для того, чтобы отсортировать массив, необходимо вызвать метод .sort или .sort_by (начиная с версии 1.8).
 
['y','nona','6bIJIa','co6aka'].sort #-> ["6bIJIa", "co6aka", "nona", "y"] сортировка по значению
['y','nona','6bIJIa','co6aka'].sort_by{ |elem| elem.size } #-> ["y", "nona", "6bIJIa", "co6aka"] сортировка по размеру строки
 
Остается только добавить, что массивы сортируются по возрастанию. А вот если вам необходимо осуществить сортировку по убыванию, то придется писать собственный метод сортировки "пузырьком". Шутка! Существует несколько путей решения этой задачи. На данный момент мы будем использовать метод .reverse, речь о котором пойдет ниже.
 
==== Обращение (перевертывание) массива ====
 
'''Определение''': ''Обращение массива &mdash это процесс изменения порядка элементов на обратный, т.е. первый элемент становится последним, второй элемент предпоследним и т.д.''
 
Для обращения массива существует метод .reverse. Применим его к предыдущим примерам, чтобы получить сортировку по убыванию:
 
['y','nona','6bIJIa','co6aka'].sort.reverse #-> ["y", "nona", "co6aka", "6bIJIa"]
['y','nona','6bIJIa','co6aka'].sort_by{ |elem| elem.size }.reverse #-> ["co6aka", "6bIJIa", "nona", "y"]
 
Обратите свое внимание на то, как мы примененили метод .reverse: мы его просто "прицепили" в конец предудущего примера. Таким образом Ruby-программисты избавляются от лишних переменных (не надо хранить промежуточный результат).
 
==== Сложение/вычитание массивов ====
 
 
==== Объединение и пересечение массивов (как множеств) ====
 
 
=== Итераторы ===
 
=== Хитрости ===
 
Задача: необходимо сгенерировать пароль, состоящий из восьми различных чисел или латинских букв.
 
cumBoJIbI = ['a'..'z','A'..'Z','0'..'9'].map{ |range| range.to_a }.flatten
puts (0...8).map{ cumBoJIbI[ rand( cumBoJIbI.size ) ] }.join
 
=== Задачи ===
==== Одномерные ====