算法将对象添加到数组中,而无需突变原始数组



我有一系列未决的付款作为对象,我想同时了解所有付款的总额,因为它们是同一商店的。当函数正确计算后调用该函数时,当我再次调用它时,它会突变对象的原始数组。我不明白为什么当我映射它时它会突变。

我需要函数不要突变对象的原始数组。它应该进行计算,然后给我结果。如果再次调用,它也不应在当前总和上添加。它应该从头开始。

let pending = [ 
{Date: "20/12/2018",
Company:[ 
{Name: "Asda", Amount: 5.5},
{Name: "M&S", Amount: 10},
{Name: "Nisa", Amount: 15},
{Name: "Iceland", Amount: 10},
{Name: "Tesco", Amount: 5}
]},
{Date: "20/12/2018",
Company:[ 
{Name: "Asda", Amount: 5.5},
{Name: "M&S", Amount: 10},
{Name: "Nisa", Amount: 15},
{Name: "Iceland", Amount: 10},
{Name: "Tesco", Amount: 5}
]},
{Date: "20/12/2018",
Company:[ 
{Name: "Asda", Amount: 5.5},
{Name: "M&S", Amount: 10},
{Name: "Nisa", Amount: 15},
{Name: "Iceland", Amount: 10},
{Name: "Tesco", Amount: 5}
]},
{Date: "20/12/2018",
Company:[ 
{Name: "Asda", Amount: 5.5},
{Name: "M&S", Amount: 10},
{Name: "Nisa", Amount: 15},
{Name: "Iceland", Amount: 10},
{Name: "Tesco", Amount: 5}
]}
]
function returnSpendTotals() {
  let sumSpend = []
  let spendArray = pending.map(activities => activities.Company)
  spendArray.flat().forEach(spend => {
    let shopName = sumSpend.find(item => item.Name === spend.Name)
    if (shopName) {
      shopName.Amount += spend.Amount
    } else {
      sumSpend.push(spend)
    }
  })
  return sumSpend
}

每次我致电returnspendtotals()

时,它应该返回
[{Name: "Asda", Amount: 22},
{Name: "M&S", Amount: 40},
{Name: "Nisa", Amount: 60},
{Name: "Iceland", Amount: 40},
{Name: "Tesco", Amount: 20}]

但是,如果我第二次称其为我得到的

[{Name: "Asda", Amount: 38.5},
{Name: "M&S", Amount: 70},
{Name: "Nisa", Amount: 105},
{Name: "Iceland", Amount: 70},
{Name: "Tesco", Amount: 35}]

现在等待的第一个对象是

{Company: [
{Name: "Asda", Amount: 38.5},
{Name: "M&S", Amount: 70},
{Name: "Nisa", Amount: 105},
{Name: "Iceland", Amount: 70},
{Name: "Tesco", Amount: 35}],
Date: "20/12/2018"}

,待处理中的其余对象不变

您可以采用破坏性的属性并为结果集构建一个新对象,以防止相同的对象引用对使用的数据。

function returnSpendTotals() {
    return pending.reduce((r, { Company }) => {
        Company.forEach(({ Name, Amount }) => {
            let shop = r.find(item => item.Name === Name)
            if (shop) {
                shop.Amount += Amount;
            } else {
                r.push({ Name, Amount });
            }
        });
        return r;
    }, []);
}
let pending = [{ Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }, { Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }, { Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }, { Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }];
console.log(returnSpendTotals());

找到商店时:

let shopName = sumSpend.find(item => item.Name === spend.Name)

您将A 参考获得到数据结构的一部分的对象。然后您的代码修改该对象:

      shopName.Amount += spend.Amount

我不确定该解决方案的确切建议是什么,因为这并不完全清楚您要做什么。可能您应该保留一个单独的总运行,而不是更改"商店"对象。

还请注意,.map()在您的功能中较早过程:

let spendArray = pending.map(activities => activities.Company)

类似地导致由参考文献返回原始数据结构的列表中。

使用此解决方案,它很简单,有效,没有花哨的进行,只需创建一个对象,将属性分配给该对象,然后在数据对象上迭代。

const data=[{Date:"20/12/2018",Company:[{Name:"Asda",Amount:5.5},{Name:"M&S",Amount:10},{Name:"Nisa",Amount:15},{Name:"Iceland",Amount:10},{Name:"Tesco",Amount:5}]},{Date:"20/12/2018",Company:[{Name:"Asda",Amount:5.5},{Name:"M&S",Amount:10},{Name:"Nisa",Amount:15},{Name:"Iceland",Amount:10},{Name:"Tesco",Amount:5}]},{Date:"20/12/2018",Company:[{Name:"Asda",Amount:5.5},{Name:"M&S",Amount:10},{Name:"Nisa",Amount:15},{Name:"Iceland",Amount:10},{Name:"Tesco",Amount:5}]},{Date:"20/12/2018",Company:[{Name:"Asda",Amount:5.5},{Name:"M&S",Amount:10},{Name:"Nisa",Amount:15},{Name:"Iceland",Amount:10},{Name:"Tesco",Amount:5}]}];
const companies = {}; 
data.forEach(obj => obj.Company.forEach(o => {
  companies[o.Name] = companies[o.Name] == null ? 0 : companies[o.Name];
  companies[o.Name] += o.Amount;
}));
console.log(companies);

编辑

这个非常相似,只花了一点花哨...这是受Nina Scholz的答案的启发,我是语法的粉丝。

const pending = [{ Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }, { Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }, { Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }, { Date: "20/12/2018", Company: [{ Name: "Asda", Amount: 5.5 }, { Name: "M&S", Amount: 10 }, { Name: "Nisa", Amount: 15 }, { Name: "Iceland", Amount: 10 }, { Name: "Tesco", Amount: 5 }] }];
const compelte = pending.reduce((r, { Company }) => {
  Company.forEach(({ Name, Amount }) => r[Name] == null ? r[Name] = 0 : r[Name] += Amount);
  return r;
}, {});
console.log(compelte);

function returnSpendTotals() {
  let companies = {}
  pending.forEach(item => {
      item.Company.forEach(company => {
          if (!companies[company.Name]) {
              companies[company.Name] = company.Amount;
          } else {
              companies[company.Name] += company.Amount;
          }
      })
  })
  return companies
}
returnSpendTotals(pending)
// result:  {Asda: 22, M&S: 40, Nisa: 60, Iceland: 40, Tesco: 20}

最新更新