Вероятно, проблема FizzBuzz — самый простой и часто задаваемый вопрос в мире собеседований по программированию. Это быстрый и простой способ проверить способность разработчика к построению логики.

В проблеме указано:

Выведите все целые числа от 1 до N. Но для чисел, кратных 3, вместо числа выведите «Fizz». Если число кратно 5, напечатайте «Buzz» вместо числа. Для чисел, кратных 3 и 5, вместо числа напечатайте «FizzBuzz».

Традиционный подход может выглядеть примерно так.

const genarateFizzBuzzString = i => {
    if (i % 15 === 0) {
      return "FizzBuzz";
    } else if (i % 5 === 0) {
      return "Buzz";
    } else if (i % 3 === 0) {
      return "Fizz";
    }
    return i;
  };
for (let i = 1; i <= 15; i++)       console.log(`${genarateFizzBuzzString(i)} \n`);

Но в этой функции много операторов if-else и несколько операторов return. Мы видим много возможностей для оптимизации. Возможно, более оптимизированный способ решения

const genarateFizzBuzzString = i => {
    let str = "";
    
    if (i % 3 === 0) str += "Fizz";
    if (i % 5 === 0) str += "Buzz";
    return str || i;
};
for (let i = 1; i <= 15; i++) console.log(`${genarateFizzBuzzString(i)} \n`);

Это будет приемлемое решение, легко поддерживаемое и читабельное.

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

Почему функциональное программирование?

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

Есть много способов решить эту проблему с помощью FP. но основное выглядит примерно так.

const chainCondition = (str, divisor) => dividend => 
    (next = dividend) =>
      dividend % divisor == 0 
      ? str + (next === dividend ? "" : next) 
      : next;
const fizz = chainCondition("Fizz", 3);
const buzz = chainCondition("Buzz", 5);
const genarateFizzBuzzString = i => fizz(i)(buzz(i)());
for (let i = 1; i <= 15; i++) 
     console.log(`${genarateFizzBuzzString(i)} \n`);

chainCondition — это чисто функциональная реализация, которую можно использовать модульно во всем коде.

Давайте быстро добавим новое условие, в котором вам нужно печатать «Zazz» всякий раз, когда число кратно 7.

const fizz = chainCondition("Fizz", 3);
const buzz = chainCondition("Buzz", 5);
const zazz = chainCondition("Zazz", 7);
const genarateFizzBuzzString = i => fizz(i)(buzz(i)(zazz(i)()));