Александр Абоимов

Второй раз уже вижу такой код в решении учителя. Вы перед применением функции reduce преобразовываете структуру, используя другие функции(filter и map в этом уроке), возникает вопрос зачем? Ведь можно обойтись просто функцией reduce, решение получится таким же лаконичным, читабельным, даже, в лекции говорилось о том, что она является аналогом применения map и filter. На мой взгляд получается излишнее нагромождение функций.

5 0

Kirill Mokevnin

Такое ощущение что вы написали этот пост не посмотрев урок), потому что именно в нем и объясняется почему так делать не надо. Главная идея в том что мы разбиваем задачу на подзадачи (разделяй и властвуй), и вместо одного большого блока, который требует держать в голове кучу деталей, мы решаем последовательно множество тривиальных задач. Причем, чаще всего, они один в один соответствуют формулировке самой задаче. Типичный код на фп языках и тех где развиты функции высшего порядка, это цепочки из filter/map/reduce. В тех же clojure/haskell подобных ФВП просто сотни, с помощью них можно чудеса творить. Особенно все это становится актуально, когда вы в код смотрите спустя хотя бы пару недель.

2

Kirill Mokevnin

Вот посмотрите пример https://github.com/hexlet-codebattle/battle_asserts/blob/master/src/battle_asserts/issues/array_interleave.clj

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

И другой пример из хаскеля:

ghci> sum (takeWhile (<10000) (filter odd (map (^2) [1..])))  
166650  

Даже не зная языка можно восстановить задачу и понять что происходит.

3

Александр Абоимов

Спасибо за развернутый ответ с примерами. А зачем такой большой подробный дескрипшн к коду в примере?:) По сути, я согласен с вами по поводу разделения задачи на подзадачи. Спрошу по своему коду и ближе к реальной жизни:

export const wordsCount = (tag, word, html) => reduce((item, acc) => {
  if (is(tag, item)) {
    return wc(word, value(item)) + acc;
  }
  return acc;
}, 0, html);

В этой простой задаче, на мой взгляд, нет необходимости в разделении и протаскивании данных, если их можно сделать одной функцией, в том же Хаскеле есть функции типа mapReduce, flatMap и т.д. В данном примере намерения в коде соответствуют тому, для чего нужна функция reduce. Если в переданной лямбде было бы больше действий и строк кода соответственно стало больше, тогда бы однозначно надо было декомпозировать. Но я пойму, если такое решение было сделано для показательно-образовательных целей. P.S.: урок смотрел)

0

Kirill Mokevnin

Несмотря на то что вы не выделили фильтрацию, она у вас есть в редьюсе. Мы учим (и сами так делаем) что разделять надо, а слушать нас или нет это вы сами решайте).

0

Александр Абоимов

Хорошо, продолжаем учиться :)

0

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг».

Похожие вопросы

Denis 3 дня назад →

Добрый вечер! Почему "Выше конкуренция" не является в том числе корректным ответом - чем больше видов отвер...

Gennadiy Zinchenko 14 марта 2020 →

Добрый день! Заметил что фильтрация для первой и второй функции повторяется и вывел её в отдельную функцию....

user-c31120ab1bca3fd8 13 февраля 2020 →

Здравствуйте. Добавьте, пожалуйста, конспект по этому уроку и предыдущему

Вячеслав Пилин 15 января 2020 →

Здравствуйте. Подтолкните с решением https://ru.hexlet.io/code_reviews/195289.И как выводить промежуточный ...

Владислав Кунгуров 14 января 2020 →

Подскажите пожалуйста, дошел до этого шага и сегодня увидел, что полностью поменяли профессию фронтэнд JS, ...