J'ai cet exemple de tableau d'objets

   mangoes:[
      { quantity:5},
      { quantity:8},
      { quantity:13},
      { quantity:4}
    ]

Lorsque je supprime x mangues, ce x doit être soustrait du premier élément du tableau, et si ce x dépasse le premier élément, il devrait réduire la quantité restante dans le deuxième élément du tableau ... et ainsi de suite.

C'est-à-dire que j'ai besoin que la quantité soit réduite à partir du premier du tableau jusqu'au second s'il dépasse, au troisième etc.

Par exemple, si j'achète 2 mangues, il devrait moins 2 dans le premier élément du tableau et le tableau de mangues résultant devrait être

   mangoes:[
      { quantity:3},
      { quantity:8},
      { quantity:13},
      { quantity:4}
    ]

D'un autre côté, si j'aurais acheté 7 mangues, cela devrait réduire les 5 du premier élément du tableau, puis supprimer 2 mangues du deuxième élément ... et donc le tableau final serait comme ça ci-dessous

   mangoes:[
      { quantity:0},
      { quantity:6},
      { quantity:13},
      { quantity:4}
    ]

En utilisant Javascript, comment puis-je y parvenir?

CE QUE J'AI ESSAYÉ

J'ai essayé comme ça ci-dessous, cela ne fonctionne que pour le premier élément (cas) lorsque le x est inférieur, mais pour les autres cas, cela ne fonctionne pas;

var x = 2
var done = false

mangoes.forEach(function (item,i) {

  if(mangoes[i].quantity>=x && !done){
    item.quantity = mangoes[i].quantity - x
    done = true
  }

})
1
Amani 31 mai 2020 à 21:31

6 réponses

Meilleure réponse

Vous pouvez prendre une closure carte à l'intérieur et générer le résultat souhaité.

var mangoes=[ { quantity:5},{ quantity:8},{ quantity:13},{ quantity:4}];
var toReduce = 5;

var result = mangoes.map((num=>({quantity})=>(r = Math.min(quantity,num),num=num-r,({quantity:quantity-r})))(toReduce));

console.log(result);
1
gorak 31 mai 2020 à 19:08
const takeMangoes = (num, from) => from.map(x => {
  const take = Math.min(x.quantity, num);
  num -= take;
  // Original way, keep all properties, don't mutate original
  //return {...x, quantity: x.quantity - take};
  
  // Pick from below:

  // New way 1, mutate original in place
  x.quantity = x.quantity - take;
  return x;
  // New way 2, limit to OWN properties
  return Object.getOwnPropertyNames(x).reduce((a, c) => {
    a[c] = x[c];
    if (c === 'quantity') {
      a[c] -= take;
    }
    return a;
  }, {});
}).filter(x => x.quantity > 0);

console.log(takeMangoes(2, [
  {quantity: 5},
  {quantity: 8},
  {quantity: 13},
  {quantity: 4},
]));

console.log('------------------------');

console.log(takeMangoes(7, [
  {quantity: 5},
  {quantity: 8},
  {quantity: 13},
  {quantity: 4},
]));
2
Chase 2 juin 2020 à 19:14

Voici une fonction, il vous faut 3 paramètres:

  1. Le tableau
  2. Le montant que vous souhaitez retirer
  3. Le nom de la propriété
let mangoes = [
      { quantity:3},
      { quantity:8},
      { quantity:13},
      { quantity:4}
    ]
    
function removeItem(array, amount, property){
   let remaindAmount = amount;
   let mangoes = array.map(el => {
      if(el[property] < remaindAmount){      
         remaindAmount -= el[property];
         return { [property]: 0 };
      }
      let diff = el[property] - remaindAmount;
      remaindAmount = 0;
      return {[property]: diff };
      
   })
   return mangoes;
   
}

console.log(removeItem(mangoes, 11, "quantity"));
0
Ifaruki 31 mai 2020 à 18:57
var getMangoes = function(requested){
  var remaining = requested;
  var supplied = 0;
  for(var i = 0; i < mangoes.length() && supplied < requested; i++){
    if(mangoes[i].quantity >= remaining){
      mangoes[i].quantity -= remaining;
      supplied += remaining;
    }
    else {
      remaining -= mangoes[i].quantity;
      supplied += mangoes[i].quantity;
    }
  }
  return(supplied);
};

var mangoesIWant = 13;
var mangoesIGot = getMangoes(mangoesIWant);
0
DynasticSponge 31 mai 2020 à 18:51

Vous pouvez y parvenir avec forEach de cette façon. Mais je ne le recommanderais pas car même si une quantité est jugée supérieure à la valeur à déduire, elle bouclera toujours sur toute la liste des éléments car vous ne pouvez pas sortir d'une boucle forEach

  var mangoes = [
      { quantity:0},
      { quantity:6},
      { quantity:13},
      { quantity:4}
    ];

var x = 2
var done = false

mangoes.forEach(function (item,i) {

 if(item.quantity< x){
   item.quantity = 0;
   x = x- item.quantity; 
  }else{
   item.quantity = item.quantity-x;
   x=0;
  }

});
console.log(mangoes)

Cependant, je recommanderais d'utiliser for..of..loop pour que vous puissiez sortir conditionnellement de la boucle, c'est-à-dire que si la quantité s'avère supérieure à celles à déduire, déduisez et sortez de la boucle. Il n'y a pas besoin d'itération supplémentaire.

  var mangoes = [
      { quantity:5},
      { quantity:6},
      { quantity:13},
      { quantity:4}
    ];

var x = 1
var done = false

for(let i of mangoes){
  if(i.quantity >= x){
    i.quantity  = i.quantity -x;
    x = x - i.quantity;
    break;
  }else{
    x = x - i.quantity;
    i.quantity = 0;
  }
}

console.log(mangoes)
1
ABGR 31 mai 2020 à 19:00
let x = 8;

const newMangoes = mangoes.map((mango) => {
    if (!x) return mango;
    if (x <= mango.quantity) {
        newMango =  {quantity: mango.quantity - x};
        x = 0;
        return newMango;
    } else {
        x = x - mango.quantity;
        return {quantity: 0};
    }
});
1
Michael Mishin 31 mai 2020 à 19:00