Array.map-使用此属性递归添加新属性

时间:2018-10-13 18:04:23

标签: javascript arrays

我想使用map向数组中的所有项目动态添加新属性。但是,在将其添加到每个项目时,此属性的值是所有新添加的先前项目的属性

考虑以下示例:

let persons = [{
"name": "A",
 "salary": 2
}, {
"name": "B",
 "salary": 5
},{
"name":"C",
"salary":12
}];

我想返回:

[{
    "name": "A",
     "salary": 2,
     "sumSalary":2
    }, {
    "name": "B",
     "salary": 5,
     "sumSalary":7
    },{
    "name":"C",
    "salary":12,
    "sumSalary":19
   }];

我已经尝试过这个:

let mutatedPersons = persons.map((currentValue, index, mutatedPersons) => ({
  ...currentValue,
    sumSalary: currentValue.name === 'A' ? currentValue.salary : mutatedPersons[index - 1].sumSalary + currentValue.salary
}))

但是我一直得到这个:

[
  0: {name: "A", salary: 2, sumSalary: 2}
  1: {name: "B", salary: 5, sumSalary: NaN}
  2: {name: "C", salary: 12, sumSalary: NaN}
]

4 个答案:

答案 0 :(得分:3)

您引用的mutatedPersons是原始数组(请参见map's parameters),而不是更新的数组,后者在映射结束之前实际上并不存在。您可以将先前的总和缓存在外部变量(prevSumSalary)中,并将其用作新变量的基础:

const persons = [{ name: "A", salary: 2 }, { name: "B", salary: 5 }, { name: "C", salary: 12 }]

let prevSumSalary = 0;
const mutatedPersons = persons.map((currentValue, index) => ({
  ...currentValue,
    sumSalary: (prevSumSalary = prevSumSalary + currentValue.salary)
}))

console.log(mutatedPersons);

另一种选择是使用Array.reduce(),因为您可以访问累积值:

const persons = [{ name: "A", salary: 2 }, { name: "B", salary: 5 }, { name: "C", salary: 12 }]

const mutatedPersons = persons.reduce((r, currentValue) => [...r, 
  ({
    ...currentValue,
      sumSalary: currentValue.salary + (r.length && r[r.length - 1].sumSalary)
  })
], [])

console.log(mutatedPersons);

答案 1 :(得分:1)

您可以在sum上使用闭包,并将其用于添加的sumSalary属性。

var data = [{ name: "A", salary: 2 }, { name: "B", salary: 5 }, { name: "C", salary: 12 }],
    result = data.map((sum => o => ({ ...o, sumSalary: sum += o.salary }))(0));
    
console.log(result);

答案 2 :(得分:1)

这是Array#reduce的理想情况。

一个人可以使用累加器(整个salarySum)来直接访问最后一个salarySum值。

只要有人想到聚合函数,就应该首先想到Array#reduce

此外,我为您提供了一个解决方案,该解决方案不会使源persons发生突变,但是会创建一个新数组,其中每个项目的salarySum均会出现:

const persons = [{
  name: "A",
  salary: 2
}, {
  name: "B",
  salary: 5
}, {
  name: "C",
  salary: 12
}]

const {
  persons: persons_,
  salarySum
} = persons.reduce((result, person) =>
  result.persons.push({
    ...person,
    salarySum: (result.salarySum += person.salary)
  }) && result, {
    salarySum: 0,
    persons: []
  })

console.log(persons_)
console.log(salarySum)

答案 3 :(得分:0)

let persons = [{
"name": "A",
 "salary": 2
}, {
"name": "B",
 "salary": 5
},{
"name":"C",
"salary":12
}];

let sum = 0;
persons.map(curr => {
  sum += curr.salary;
  curr.sumSalary = sum;
});

console.log(persons);