簡體   English   中英

在不改變原始數組的情況下在數組中添加對象的算法

[英]algorithm to add up objects in an array without mutating the original array

我有一系列待處理的付款作為對象,我想知道同一家商店的所有付款的總和。 一旦函數正確計算就調用該函數,當我再次調用該函數時,它將使對象的原始數組發生變化。 我不明白為什么要在其上進行映射時對其進行突變。

我需要該功能不使對象的原始數組發生變異。 它應該進行計算,只是給我結果。 如果再次調用,則也不會將當前總和相加。 它應該從頭開始。

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"}

其余待處理的對象保持不變

當您找到一家商店時:

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

您可以獲得數據結構中的對象的引用 然后,您的代碼修改該對象:

      shopName.Amount += spend.Amount

我不確定確切的建議是解決方案,因為尚不清楚您要做什么。 可能您應該保持單獨的運行總計,而不是更改“ shop”對象。

還要注意, .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() { 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()); 

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}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM