How to decrement items in array Incrementally based on the given quantity in Javascript

眉间皱痕 提交于 2021-02-19 08:01:08

问题


I have this sample array of objects

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

When I remove x mangoes, that x should be subtracted from the first element in the array, and if that x exceed the first element then it should reduce the remained quantity in the second item in the array...and so forth.

This is to say, I need the quantity to be reduced starting from the first one in the array down to the second if it exceed, to the third etc..

For example, If I buy 2 mangoes, It should minus 2 in the first array element and the resulting mangoes array should be

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

On the other hand, If I would have bought 7 mangoes, it should reduce all 5 from first array element and then remove 2 mangoes from the second element...and hence the final array would be like this below

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

By Using Javascript, how can I achieve this?

WHAT I HAVE TRIED

I have tried like this below, It works only for the first element(case) when the x is less, but for other case it doesn't work;

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:


You can take a closure inside map and generate the desired result.

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



回答2:


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},
]));



回答3:


You can achieve that with forEach this way. But I wouldn't recommend it because even if a quantity is found to be greater than the value to be deducted, it will still loop through the whole item list as you can't break out of a forEach loop

  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)

However, I would recommend using for..of..loop so that you could conditionally break out of the loop, i.e if the quantity is found to be greater than the ones to be deducted, just deduct and break out of the loop. There's no need of further iteration.

  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)



回答4:


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



回答5:


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


来源:https://stackoverflow.com/questions/62120767/how-to-decrement-items-in-array-incrementally-based-on-the-given-quantity-in-jav

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!