问题
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