JavaScript:从另一个元素较多的数组生成元素较少的数组的功能性方法



我正在尝试这样做:我有一个带有销售细节的对象数组,格式为:

[
{
product:Banana,
quantity:34,
...(other fields)
},
{
product:Apple,
quantity:11,
...(other fields)
},
{
product:Banana,
quantity:15,
...(other fields)
},
{
product:Apple,
quantity:9,
...(other fields)
},
{
product:Orange,
quantity:7,
...(other fields)
}
]

从这个数组中,我想创建一个新的数组,原始数组中每个产品只有一个字段,每个产品的总数量都在细节上,如下所示:

[
{
product:Banana,
quantity:49 //(34 + 15) from the original array
},
{
product:Apple,
quantity:20 //(11 + 9) from the original array
},

{
product:Orange,
quantity:7 //Just 7 from the original array
}
]

目前,我有一个实际工作的代码(变量名是西班牙语(:

const validarDetalle  = async function (detalle) { 
//'detalle' is the original array received by parameter


let error=false;



let arrayProductosCantidades=[]; //This is the new array which I'm generating

//I iterate on the original array with a for
for (const elemDetalle of detalle) {

console.log(elemDetalle);
//When the new array it's initially empty, I just concatenate
//the first product and quantity found on the original array to it

if(arrayProductosCantidades.length==0) {

arrayProductosCantidades=arrayProductosCantidades.concat(
{
producto:elemDetalle.producto,
cantidad:Number(elemDetalle.cantidad)

});
}

//If it isn't empty, I look if the product of the element
//of the original array 
//where I'm standing already exists on the new array
else if(
(!arrayProductosCantidades.some (
function(productoCantidad) {
return (productoCantidad.producto == elemDetalle.producto)
}
)
)
)

{

//If it doesn't exists, I concatenate an element to the new array
//with the product and quantity of that element of the original array
arrayProductosCantidades=arrayProductosCantidades.concat(
{
producto:elemDetalle.producto,
cantidad:Number(elemDetalle.cantidad)

}
);
}
//If the product already exists on the new array,
//I create a variable 'elementoProductoCantidad' with the
//previous value of that element in the new array
else{
let elementoProductoCantidad=
arrayProductosCantidades.find (
function(productoCantidad) {
return(productoCantidad.producto == elemDetalle.producto)

}
);
//In that variable, I update the quantity field, adding to it the quantity
//of the element of the original array in where I'm standing 
elementoProductoCantidad.cantidad += Number(elemDetalle.cantidad);

//After that, I delete the element of the new array with the old quantity value
arrayProductosCantidades=arrayProductosCantidades.filter(prodCant => prodCant.producto!=elemDetalle.producto);

//Finally I concatenate it again, with the quantity value updated
arrayProductosCantidades=arrayProductosCantidades.concat(elementoProductoCantidad);
}
}

console.log(arrayProductosCantidades);


//Once I've generated the new array, I make a validation for every product existing in my database 
//(I should never get a negative stock in any product sold)

for (const elemProdCant of arrayProductosCantidades) {

const producto = await Number(elemProdCant.producto);
const cantidad = await Number(elemProdCant.cantidad);

let productoActualizado= await Producto.findById(elemProdCant.producto);


if(Number(productoActualizado.stock) - Number(cantidad) < 0) {
error=true;
}
}


return error;

}

尽管这很好,但我认为这应该是一种更好的方法,可以用函数的方式来实现,使用map和reduce等函数来代替循环。

有人知道这是否可能和/或方便吗?非常感谢!

一个简单的方法是首先构建一个quantityByProduct对象(查找表(,其中包含每个产品的总数量,然后使用它来构建对象的最终数组。

const inputs = [{
product: 'Banana',
quantity: 34,
}, {
product: 'Apple',
quantity: 11,
}, {
product: 'Banana',
quantity: 15,
}, {
product: 'Apple',
quantity: 9,
}, {
product: 'Orange',
quantity: 7,
}];
const quantityByProduct = {};
for (let input of inputs) {
quantityByProduct[input.product] = quantityByProduct[input.product] || 0;
quantityByProduct[input.product] += input.quantity;
}
const output = [];
for (let product in quantityByProduct) {
const quantity = quantityByProduct[product];
output.push({
product,
quantity
});
}
console.log(output);

const arr = [{
product: 'Banana',
quantity: 34,
},
{
product: 'Apple',
quantity: 11,
},
{
product: 'Banana',
quantity: 15,
},
{
product: 'Apple',
quantity: 9,
},
{
product: 'Orange',
quantity: 7,
}
];
const partition = (arr, fn, fn2) =>
arr.reduce(
(acc, val, i, arr) => {
acc[fn(val, i, arr) ? 0 : fn2(val, i, arr) ? 1: 2].push(val);
return acc;
},
[[], [], []]
);
const isBanana = obj => obj.product === 'Banana';
const isApple = obj => obj.product === 'Apple';
const result = partition(arr, isBanana, isApple).map((p) => {
return {
product: p[0].product,
quantity: p.reduce((acc, val) => acc + val.quantity, 0),
}
});
console.log(result); // [{ product: 'Banana', quantity: 49 },{ product: 'Apple', quantity: 20 },{ product: 'Orange', quantity: 7 }]

上面的代码利用功能方法来合并喜欢的对象

最新更新