Композиция функций. решение задачи

Рейтинг: -1Ответов: 1Опубликовано: 07.04.2023

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

на мой взгляд тут ошибка в самой задаче либо пропушена важная часть.

//PS: то что закаментировано до -------------мой ответ.  описание задачи и ожидание

// 1:
// Композиция функций - это мощный инструмент для работы, например:

const add = (x, y) => x + y;
const double = (x) => add(x, x);
double(add(2, 3)); // 10

// Но в сложных выражениях композитные функции могут быть сложны для понимания,
//  например: double(double(add(7, add(add(5, add(4, 5)), 4))))); // 100

// Куда удобнее было бы применять эти операции последовательно, слева направо.
// например:
// s.add(4,5).add(5).add(4).add(7).double().double().calculate();

// Ваша задача реализовать 'sequence' функцию:

// let s = sequence({ add, double });

// Как вы можете видеть, эта функция принимает объект
// с методами add и double и возвращает объект,
// который позволяет вам вызывать ваши методы цепочкой.
// Результат можно получить, вызвав метод 'calculate()'.

// Методы в цепочке принимают определенное количество аргументов.
// Первая функция в этой цепочке получает все аргументы.
// В последующих функциях первый аргумент - результат выполнения предыдущей функции,
// а остальные передаются вручную.

// Стоит учесть, что цепочки могут быть переиспользованы:

// s.add(4,5).add(5).add(4).add(7).double().double().calculate(); // 100
// s.add(3, 4).calculate(); // 7
// s.add(1, 2).calculate(); // 3
// let s1 = s.add(1, 2); s1.calculate(); // == add(1, 2) == 3
// s1.double().calculate(); // == double(add(1, 2)) == 6
// s1.add(1).calculate(); // == add(add(1, 2), 1) == 4
// s1.calculate(); // == add(1, 2) == 3
// let s2 = s1.add(5); s2.double().calculate(); // == double(add(add(1, 2), 5)) == 16
// s2.add(3).calculate(); // == add(s1.add(add(1, 2), 5), 3) == 11
// s2.calculate(); // == add(add(1, 2), 5) == 8
// s1.calculate(); // == add(1, 2) == 3

// Все приведенные примеры основаны на реализации add и double как функций
// сложения и удвоения численных аргументов для удобства отладки.
// Однако передача функций add и double параметрами в sequence позволяет
// абстрагироваться от их реализации. В sequence могут быть переданы
// функции add и double оперирующие строками или более сложными объектами.

// Функция sequence должна успешно проходить все указанные тест-кейсы

//-------------мой ответ.

// на мой взглят тут ошибка в ожидании:
// s1.double().calculate();

// поскольку:
// s.add(3, 4).calculate(); // 7
// s.add(1, 2).calculate(); // 3

// получается calculate должен обнулят резултат так?

// либо я что то не разобрал, внизу моя реализация которая ламается на строке s1.double().calculate();

const getSequence = (functions) => {
  const initialValue = 0;
  getSequence.res = initialValue;
  const initialObject = {
    calculate: () => {
      let copyRes = getSequence.res;
      getSequence.res = initialValue;
      return copyRes;
    },
  };
  for (const key in functions) {
    initialObject[key] = function (...args) {
      if (getSequence.res) {
        getSequence.res = functions[key](getSequence.res, ...args);
      } else {
        getSequence.res = functions[key](...args);
      }
      return this;
    };
  }

  return initialObject;
};

let s = getSequence({ add, double });

console.log(s.add(4, 5).add(5).add(4).add(7).double().double().calculate()); // 100)
console.log(s.add(3, 4).calculate()); // 7)
console.log(s.add(1, 2).calculate()); // 3)

let s1 = s.add(1, 2);

console.log(s1.calculate()); // == add(1, 2) == 3)
console.log(s1.double().calculate()); // == double(add(1, 2)) == 6)
console.log(s1.add(1).calculate()); // == add(add(1, 2), 1) == 4)
console.log(s1.calculate()); // == add(1, 2) == 3)

let s2 = s1.add(5);

console.log(s2.double().calculate()); // == double(add(add(1, 2), 5)) == 16)
console.log(s2.add(3).calculate()); // == add(s1.add(add(1, 2), 5), 3) == 11)
console.log(s2.calculate()); // == add(add(1, 2), 5) == 8)
console.log(s1.calculate()); // == add(1, 2) == 3)

Ответы

▲ 0Принят

Задача поставлена корректно. Ошибка в вашем решении - не нужно было переиспользовать один и тот-же объект много раз.

sequence возвращает первичный объект. В нём нет метода calculate. Все остальные методы повторяют вычисление соответствующей функции и возвращают вторичный объект.

Вторичный объект уже имеет метод calculate. Остальные его методы принимают на один аргумент меньше чем соответствующая функция. Вместо первого аргумента - значение переданное при создании вторичного объекта:

const apply = (f, args) =>{
    console.assert(f.length === args.length);
    return f(...args);
};

const sequence = fs => {
    const secondary = value => {
        const obj = { calculate: () => value };
        for (const [name, f] of Object.entries(fs)) {
            console.assert(name !== 'calculate');
            obj[name] = (...args) => secondary(apply(f, [value, ...args]));
        }
        return obj;
    };

    const obj = {};
    for (const [name, f] of Object.entries(fs)) {
        obj[name] = (...args) => secondary(apply(f, args));
    }
    return obj;
};

const add = (x, y) => x + y;
const double = x => add(x, x);
const s = sequence({ add, double });

const _ = console.log;

_(s.add(4,5).add(5).add(4).add(7).double().double().calculate()); // 100
_(s.add(3, 4).calculate()); // 7
_(s.add(1, 2).calculate()); // 3

const s1 = s.add(1, 2);
_(s1.calculate()); // == add(1, 2) == 3
_(s1.double().calculate()); // == double(add(1, 2)) == 6
_(s1.add(1).calculate()); // == add(add(1, 2), 1) == 4
_(s1.calculate()); // == add(1, 2) == 3

const s2 = s1.add(5);
_(s2.double().calculate()); // == double(add(add(1, 2), 5)) == 16
_(s2.add(3).calculate()); // == add(s1.add(add(1, 2), 5), 3) == 11
_(s2.calculate()); // == add(add(1, 2), 5) == 8
_(s1.calculate()); // == add(1, 2) == 3