Вы все равно можете использовать более функциональный подход, но оптимизировать способ выполнения расчетов.
Вот идея - поскольку вы пытаетесь суммировать все элементы, затем суммируете все, кроме первого, затем суммируйте все, кроме второго, et c., математически эквивалентно получению суммы с последующим вычитанием из нее каждого числа по порядку и сохранением суммы.
[sum([41, 42, 43]), sum([42, 43]), sum([43]), sum([])]
то же самое, что:
total = sum([41, 42, 43])
[total - 0, total - 0 - 41, total - 0 - 41 - 42, total - 0 - 41 - 42- 43]
совпадает с:
total = sum([41, 42, 43])
[total -= 0, total -= 41, total -= 42, total -= 43]
В обобщенном виде это выглядит так:
total = sum([a1, a2, ..., aN])
[total -= 0, total -= a1, total -= a2, ..., total -= aN]
Используя надежный Array#reduce
, мы можем получить сумма один раз. Затем мы можем получить новый массив, используя Array.map
, используя ls.map(num => total -= num)
.
Единственная проблема здесь в том, что мы получаем на один элемент меньше - мы не вычисляем начальное total -= 0
который должен существовать для всех предметов. Один из способов сделать это - добавить его в начало. [0].concat(ls)
создаст правильный массив для сопоставления. Однако, поскольку мы уже знаем, какое будет значение, мы можем пропустить этот шаг и напрямую заменить его на total
(ведь результат total -= 0
равен total
и оставляет total
без изменений). Итак, мы можем напрямую использовать [total].concat(ls.map(num => total -= num))
, чтобы начать с total
и добавить остальные элементы. до конца.
const ls = [0, 1, 3, 6, 10]
const partsSums = (ls) => {
let total = ls.reduce((a, b) => a + b, 0);
return [total]
.concat(
ls.map(num => total -= num)
);
}
console.log(partsSums(ls));