Статьи

Ruby Facets: Массивы

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

Массивы в Ruby довольно важны.

Я знаю… читая это предложение, вы можете подумать: «Массивы важны на всех языках», но это не совсем так. Есть много языков, которые побуждают вас использовать специализированные коллекции. Рубиисты склонны придерживаться базовых типов, это один из действительно прекрасных аспектов этого языка, который трудно найти.

В любом случае, работа с массивами часто подразумевает некоторые манипуляции с самим массивом. По этой причине require 'facets/array' даст вам много интересных методов, которые помогут решить ваши конкретные проблемы с большей выразительностью. Прежде чем мы начнем изучать различные методы, предлагаемые библиотекой Facets, просто добавьте в свой irbrc / pryrc следующее:

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

Если вы получили представление о том, что может предложить библиотека аспектов Ruby, попробуйте загрузить код в каталог рабочей области. Предполагая, что вы используете Git, вы можете сделать следующее:

И если вы, как и я, используете GitHub все время, то, скорее всего, вам действительно понравится Hub . Это небольшой инструмент, который отлично работает, когда вы называете его псевдонимом. Это позволяет вам делать сумасшедшие вещи, такие как git clone rails/rails , угадайте, что будет делать git fork !

Теперь, когда у вас есть библиотека локально, вы можете перейти в каталог lib/core/facets/array . Есть много файлов, и это может быть немного сложно прочитать их все. Но мы здесь, чтобы исследовать это, и нам просто нужны критерии для этого. Мы можем сгруппировать расширения для класса Array следующим образом:

  • Методы, которые добавляют семантические значения в класс Array.

  • Методы, которые выполняют какие-то вычисления и возвращают массив.

  • Методы, которые выполняют какое-то вычисление массива и возвращают строку или хэш.

Я намеренно опустил некоторые методы, потому что они были представлены в последней версии Ruby. Я имею в виду, вы знаете, что Ruby 1.8.7 представил такой хороший метод?

Это всего лишь пример, и я рекомендую вам grep для defined? в каталоге Array, потому что стандартная библиотека Ruby содержит так много хороших примеров. Я нашел интересные методы, такие как permutation просто читая источник расширения Array в библиотеке Ruby Facets.

Первая категория (о семантических вещах) — мой любимый вид расширения с общей точки зрения. Я думаю, что ключом к успеху Ruby является его выразительность. Реальная сила, которую вы имеете, — это кодирование на языке домена . Этот вид расширения, используемый с осторожностью, может добавить реальную ценность проекту и сделать программиста счастливым. Вы можете рассматривать следующие расширения как источник вдохновения для ваших конкретных задач и проектов.

Итак, начнем с семантических вещей. Следующее:

это просто псевдоним включения? метод и это можно считать глупым с первого взгляда. Но я уверен, что даже простое расширение может изменить ситуацию в проекте. Еще один интересный пример:

Да, это просто противоположность empty? и в некоторых случаях может быть полезно использовать такого рода расширение, потому что оно способствует удобочитаемости.

Последнее расширение, о котором я хочу поговорить в этой категории, действительно хороший пример того, как мало методов могут добавить реальную ценность коду. Рассмотрим следующий тривиальный пример:

А теперь рассмотрим следующее:

Справедливо сказать, что вторую версию действительно легче читать. И легче читать, значит легче поддерживать.

Теперь пришло время взглянуть на другую категорию методов. Те, которые работают с самим массивом и возвращают что-то еще. Итак, давайте начнем с двух методов, которые мне очень нравятся, before и after . Эти два метода являются противоположностями другого, и они просто возвращают элемент до (или один после) того, который вы передаете ему. Взгляните на следующий пример:

Это хорошо, не правда ли?

Теперь предположим, что у вас есть множество людей, и вы хотите собрать всех людей одного возраста. Библиотека Facets делает это довольно просто:

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

Другая очень распространенная проблема, с которой мы сталкиваемся при работе с массивами — это объединение их с разделителем и возврат строки. Очень часто Ruby предлагает метод Array#join который работает для простых случаев. Библиотека Ruby Facets предлагает версию этого метода под названием Array#conjoin которая имеет очень мощный API. Метод принимает четыре различных варианта:

  • Космос
  • распорка
  • первый
  • последний

Вы можете увидеть, как они работают в следующем примере:

Это очень гибкий API, и метод даже принимает блок. Эта функция позволяет очень сумасшедшие преобразования. Блок принимает три параметра:

Они действительно сумасшедшие, не так ли?

Теперь пришло время перейти к числу и как мы можем извлечь хорошую информацию из массивов. Предположим, например, что вы хотите знать, насколько сильно изменяется информация в массиве. Ну, библиотека Ruby Facets позволяет следующее:

Таким образом, большее число означает больше изменений. Довольно аккуратно, а? Теперь предположим, что вы хотите знать, какой элемент в вашем массиве присутствует чаще всего. В статистике это называется «режим», а библиотека Ruby Facets предлагает метод Array#mode :

Ницца. И если вы хотите узнать, сколько раз каждый элемент появляется в массиве, вы можете использовать Array#probability :

Не забудьте взглянуть на реализацию этого и других методов. Их очень интересно читать.

Пришло время поговорить о последней категории методов. Эти методы выполняют некоторые вычисления (или предоставляют способ сделать это) для массива и возвращают другой массив в качестве результата. Первый метод, который мы увидим, — это просто ярлык для более длинного вычисления, которое вы можете сделать с помощью стандартных методов Enumerable:

Как вы можете себе представить, это просто цепочки Array#flatten и Array#compact . Это простое расширение, но оно все же может помочь вам улучшить читаемость вашего кода. Библиотека предлагает еще одно простое расширение, которое может помочь. Это Array#delete_unless и это просто инверсия Array#delete_if . В некоторых ситуациях более естественно выразить намерение через Array#delete_unless . Другим интересным расширением, которое начинается с delete, является Array#delete_values и оно позволяет вам удалять несколько элементов из массива:

Просто и эффективно. Что ж, если вы имеете дело с дубликатами или неуникальными элементами, вы можете попробовать использовать facets/array/nonuniq . Этот даст вам следующие методы:

  • nonuniq / nonuniq!
  • дубликаты
  • occurrent

Давайте посмотрим на них по очереди. У метода Array#nonuniq очень понятное имя. Действительно, вы можете использовать его для извлечения массива неуникальных элементов из данного массива:

Конечно Array#nonuniq! Метод просто делает то же самое, но изменяет свой получатель. Библиотека предлагает другой метод с понятным именем, Array#duplicates . Он возвращает массив дублирующих элементов и принимает минимальное число для включения в возвращаемый массив:

Теперь рассмотрим ситуацию, когда вы должны убедиться, что массив всегда имеет одинаковый размер, например, 5, а когда ваш вход имеет размер меньше 5, вы должны добавить определенный элемент к вашему входу. Что ж, метод Array#pad может помочь вам решить эту проблему кратко:

И, как вы видели в примере, вы можете передать отрицательное число, если хотите дополнить массив из головы.

Последний метод, о котором я хочу рассказать в этой категории, очень мощный и действительно может помочь в некоторых ситуациях. Кроме того, реализация того стоит. Мы говорим о Array#recurse который позволяет рекурсивно применять блок к массиву:

Очень мощный и выразительный.

ОК, пока что все. Надеюсь, вам понравилось! Оставайтесь с нами, если вам понравился этот, потому что другие статьи идут!