У меня есть этот образец массива объектов

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

Когда я удаляю х манго, этот х должен быть вычтен из первого элемента в массиве, и если этот х превышает первый элемент, то он должен уменьшить оставшееся количество во втором элементе в массиве ... и так далее.

То есть мне нужно уменьшить количество, начиная с первого в массиве и заканчивая вторым, если оно превысит, до третьего и т. Д.

Например, если я куплю 2 манго, в первом элементе массива должно быть минус 2, а результирующий массив манго должен быть

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

С другой стороны, если бы я купил 7 манго, он должен уменьшить все 5 из первого элемента массива, а затем удалить 2 манго из второго элемента ... и, следовательно, окончательный массив будет выглядеть следующим образом

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

Используя Javascript, как мне этого добиться?

ЧТО Я ПОПРОБОВАЛ

Я попытался, как это ниже, он работает только для первого элемента (случай), когда х меньше, но для другого случая это не работает;

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 Май 2020 в 21:31

6 ответов

Лучший ответ

Вы можете взять closure внутри карты и сгенерировать желаемый результат.

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 Май 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 Июн 2020 в 19:14

Здесь функция, вам нужно 3 параметра:

  1. Массив
  2. Сумма, которую вы хотите удалить
  3. Название недвижимости
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 Май 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 Май 2020 в 18:51

Вы можете достичь этого с forEach таким образом. Но я бы не рекомендовал это делать, потому что даже если было обнаружено, что количество больше, чем вычитаемое значение, оно все равно будет проходить по всему списку элементов, поскольку вы не можете выйти из цикла 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)

Тем не менее, я бы порекомендовал использовать for..of..loop, чтобы вы могли условно выйти из цикла, т. Е. Если окажется, что количество больше, чем вычитаемое, просто вычтите и вырвитесь из цикла. Нет необходимости в дальнейшей итерации.

  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 Май 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 Май 2020 в 19:00