2 votes

Algorithme pour ajouter des objets dans un tableau sans modifier le tableau d'origine

J'ai un tableau de paiements en attente sous forme d'objets et je veux connaître le total de tous les paiements ensemble car ils sont pour les mêmes magasins. Quand la fonction est appelée une fois, elle calcule correctement, mais quand je l'appelle à nouveau, elle mute le tableau d'objets original. Je ne comprends pas pourquoi il le mute lorsque je fais un map dessus.

J'ai besoin que la fonction ne mute pas le tableau d'objets original. Elle devrait faire le calcul et me donner juste le résultat. Elle ne devrait pas rajouter sur la somme actuelle si elle est appelée à nouveau. Elle devrait le refaire complètement.

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
}

ça devrait retourner à chaque fois que j'appelle returnSpendTotals()

[{Name: "Asda", Amount: 22},
{Name: "M&S", Amount: 40},
{Name: "Nisa", Amount: 60},
{Name: "Iceland", Amount: 40},
{Name: "Tesco", Amount: 20}]

Mais si je l'appelle une deuxième fois, voici ce que j'obtiens

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

et le premier objet de pending est maintenant

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

Et le reste des objets dans pending sont inchangés

1voto

Pointy Points 172438

Lorsque vous trouvez un magasin :

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

vous obtenez une référence à un objet qui fait partie de votre structure de données. Votre code modifie ensuite cet objet :

      nomMagasin.Montant += spend.Montant

Je ne suis pas sûr de ce que suggérer comme solution car il n'est pas tout à fait clair ce que vous essayez de faire. Probablement vous devriez garder un total en cours séparé au lieu de modifier vos objets "magasin".

Notez également que le processus .map() plus tôt dans votre fonction :

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

résulte de même en une liste composée de références renvoyant à la structure de données originale.

1voto

JO3-W3B-D3V Points 1532

Avec cette solution, c'est simple, ça marche, rien de spécial, il suffit de créer un objet, d'assigner des propriétés à cet objet, et de parcourir l'objet de données, c'est tout.

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);

Éditer

Celui-ci est assez similaire, juste un peu plus sophistiqué... Cela est inspiré de la réponse de Nina Scholz, j'apprécie la syntaxe.

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);

1voto

Nina Scholz Points 17120

Vous pourriez prendre les propriétés déstructurées et construire un nouvel objet pour l'ensemble des résultats, afin d'éviter une référence à un même objet pour les données utilisées.

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());

0voto

Uma Points 796
fonction returnSpendTotals() {
  let entreprises = {}
  pending.forEach(item => {
      item.Company.forEach(company => {
          if (!entreprises[company.Name]) {
              entreprises[company.Name] = company.Amount;
          } else {
              entreprises[company.Name] += company.Amount;
          }
      })
  })
  return entreprises
}

returnSpendTotals(pending)

// résultat:  {Asda: 22, M&S: 40, Nisa: 60, Iceland: 40, Tesco: 20}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X