Композиция функций. решение задачи
можете глянуть на некую реализацию задачи, я что то сильно сомневаюсь что не правильно решил
на мой взгляд тут ошибка в самой задаче либо пропушена важная часть.
//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)
Ответы (1 шт):
Автор решения: Stanislav Volodarskiy
→ Ссылка
Задача поставлена корректно. Ошибка в вашем решении - не нужно было переиспользовать один и тот-же объект много раз.
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