kbook


Project maintained by atilla777 Hosted on GitHub Pages — Theme by mattgraham
Главная страница
Ruby

По отработке задач в Exercism

Использование методов с “говорящими” названиями

На примере проверки пустых или нулевых значений.

Плохо

объект ==  0

Хорошо

объект.zero?

Плохо

объект ==  ''

Хорошо

объект.empty?

Слипание массивов

массив1 = [1, 2]
массив2 = ['a','b']
массив1.zip(массив2) # [[1, 'a'], [2, 'b' ]]

Разница времени в секундах

Time.new(1977, 18, 4, 5, 5,5) - Time.new(1977, 18, 4, 5, 5,5)

Удаление из строки символов или замена символов с строке

строка.tr('a-z', '')
строка.tr('abc', '')
строка.tr('0-9', '')

Замена символов в строке

'AAABBBCCC'.tr('ABC', '123') # '111222333'

Замена подстрок в строке (в примере - вырезание символов пунктуации):

'слово слово слово'.gsub([[:punct:]])

Массив слов из строки

'слово слово слово'.scan(/\b[\w]+\b/)

Объект типа Method

Для передачи метода в качестве параметра функции или блока создается обхект класса Method.

Пример - приемник метода является указанный объект, параметром метода поочередно будет каждый элемент массива

массив.map(&объект.method(:метод))
объект = -> (элемент) { метод(элемент)}

Хэш из сгруппированных одинаковых элементов массива

Под одним ключем хэша группируются элементы с одинаковым результатом вычисления блока.

Ключ в таком хэше равен результату вычисления.

массив.group_by { |элемент| элемент}

Или, с учетом того, что метод #itself возвращает сам объект (приемник этого метода)

массив.group_by(&:itself)

Преобразование значений хэша

хэш.transform_values { |элемент| элемент.count}

или

хэш.transform_values(&:count)

Проверка попадания в диапазон

(диапазон).cover?(значение)

Использование объекта класса Lazy для работы с бесконечнсостями

Ряд функций Enumerable (select, map и т.п.) можно преобразовать в объект класса Lazy.

Вычисления в Lazy объекте не выполняются сразу от первого метода в цепочке, а производятся с учетом всего выражения в цепочке.

(2..Float::INFINITY).lazy
                    .select { |n| условие c n }
                    .first(количество)
                    .last

Где #first(количество) - возращает указанное количество первых элементов

Значения по умолчанию для хэша

Если происходит обращение к хэшу, созданному с помощью Hash.new с параметром в виде значения или блока, посредством ключа, для которого нет значений в хэше, то вместо nil будет возращаться определенное в параметре или блоке значение.

Hash.new(значение)

или

Hash.new {|hash, key| hash[:key] = значение}

Index в map

['a', 'b', 'c'].map.each_with_index {|element, index| код}

Reduce и inject

Методы #reduce и #inject псевдонимы, каждый из которых испльзуется в зависимости от текущего контекста кода.

Если аргумент блок, то используется #inject.

Если аргумент символ, то применяется #reduce.

Если необходимо только порссумировать все элементы, то вместо #inject или #reduce лучше использовать #sum. Пример - вычисление факториала

def fact(number)
  (1..number).reduce(:*)
end

Хвостовая рекурсия

Рекурсивный вызов должен быть последним выражением в рекурсивной функции.

При использовании хвостовой рекурсии вместо помещения текущей функции в стек и переходу к выполнению новой функции, выполнение функции начинается сначала но с новыми параметрами, взятыми из последнего выражения функции (выражение с рекурсивным вызовом).

Хвостовая рекурсия должна быть включена в компиляторе, а также а рекурсивный метод должен быть определен на этапе компиляции

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

eval <<~END
  def for(number, factor = 2, accum = [])
     #…
    def for(number, factor, accum)
  end
END