Помимо конструкторов, таких как range
и spread
, есть и другой способ создания новых колец - манипулирование существующими кольцами.
Чтобы исследовать это, возьмём простое кольцо:
(ring 10, 20, 30, 40, 50)
Что, если мы хотим перевернуть его задом наперёд? Тогда мы используем связанный метод .reverse
, который разворачивает кольцо в обратную сторону:
(ring 10, 20, 30, 40, 50).reverse #=> (ring 50, 40, 30, 20, 10)
Так, а что, если мы захотим получить первые три элемента кольца?
(ring 10, 20, 30, 40, 50).take(3) #=> (ring 10, 20, 30)
И, наконец, что, если мы захотим перемешать элементы кольца?
(ring 10, 20, 30, 40, 50).shuffle #=> (ring 40, 30, 10, 50, 20)
Это очень мощный способ создания новых колец. Однако, реальная мощь приходит, когда вы связываете несколько методов вместе.
Как на счёт перемешать кольцо, отбросить 1 элемент, а затем получить первые 3 элемента?
Давайте сделаем это в несколько этапов:
(ring 10, 20, 30, 40, 50)
- наше исходное кольцо(ring 10, 20, 30, 40, 50).shuffle
- перемешиваем - (ring 40, 30, 10, 50, 20)
(ring 10, 20, 30, 40, 50).shuffle.drop(1)
- отбрасываем 1 элемент - (ring 30, 10, 50, 20)
(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)
- берём 3 первых элемента - (ring 30, 10, 50)
Как вы видите, можно создавать длинные цепи из этих методов просто склеивая их вместе. Мы можем комбинировать их в любом порядке, в каком захотим, создавая чрезвычайно богатый и мощный способ генерации новых колец из существующих.
Наши кольца обладают одним очень важным свойством. Оно заключается в том, что цепные методы, описанные в этом разделе не изменяют кольца, они возвращают новые кольца. Это значит, что вы можете разделять кольцо между потоками выполнения и использовать разные методы в разных потоках, зная, что не повлияете на другой поток, использующий то же самое кольцо.
Вот список доступных для вас цепных методов:
.reverse
- возвращает отсортированную в обратном порядке версию кольца.sort
- возвращает отсортированную версию кольца.shuffle
- возвращает отсортированную в случайном порядке версию кольца.pick (3)
- возвращает кольцо с результатами вызова .choose
3 раза.pick (3)
- возвращает кольцо с результатами вызова .choose
3 раза.take(5)
- возвращает кольцо, содержащее первые 5 элементов исходного кольца.drop(3)
- возвращает кольцо, содержащее все элементы исходного кольца, кроме первых 3 элементов.butlast
- возвращает новое кольцо с отсутствующим последним элементом.drop_last(3)
- возвращает новое кольцо с отсутствующими 3 последними элементами.take_last(6)
- возвращает кольцо, содержащее последние 6 элементов исходного кольца.stretch(2)
- повторяет каждый элемент кольца дважды.repeat(3)
- повторяет всё кольцо 3 раза.mirror
- добавляет кольцо к перевёрнутой версии себя.reflect
- то же, что и .mirror
, но не дублирует средний элемент.scale(2)
- возвращает новое кольцо все элементы которого умножены на 2 (если кольцо содержит только числа)Конечно, цепные методы, принимающие числовые аргументы, могут принимать и другие числа! Так что не стесняйтесь вызывать .drop(5)
вместо .drop(3)
, если вы хотите отбросить первые 5 элементов кольца.