我有以下两个JavaScript对象数组:
const types = [
{
id: 1,
name: 'Paint',
unit: 'L',
},
{
id: 2,
name: 'Resin',
unit: 'mL',
},
{
id: 3,
name: 'Fiberglass',
unit: 'yd',
}
];
const items = [
{
id: 1,
type_id: 1,
name: 'Brand x paint',
qty: 5,
},
{
id: 2,
type_id: 1,
name: 'Brand y paint',
supplier: 'brand y',
qty: 3,
},
{
id: 3,
type_id: 2,
name: 'Brand x resin',
qty: 5,
},
{
id: 3,
type_id: 2,
name: 'Brand y resin',
qty: 2,
},
{
id: 3,
type_id: 2,
name: 'Brand z resin',
qty: 3,
},
{
id: 3,
type_id: 2,
name: 'Brand x fiberglass',
qty: 7,
},
{
id: 3,
type_id: 2,
name: 'Brand y fiberglass',
qty: 9,
},
];
我想用具有额外属性的类型数组创建一个新数组,该属性是每种类型的数量之和。我想出了映射类型数组的功能,并在函数内部分配了一个新属性,如totalQty,它等于类型的已过滤项,然后用求和累加器进行归约。像这样的事情,在过滤部分的某个地方非常错误:
const itemTypes = types.map( (type) => {
type.total_qty = items
.filter((items) => items.type_id === type.id)
.reduce((sum, item) => sum += item.qty, 0)
}
)
我只是想做上述工作,但是如果有更好的方法在类型旁边添加total_quantity属性,那么我愿意提出建议。预先感谢!
答案 0 :(得分:1)
问题是您使用map
的回调中没有return
,而是 mutate 给定数组。因此,map
返回undefined
值,同时types
数组已更新(但未输出)。
这是使用Map
以避免嵌套迭代的更有效的方法。因此,它以 O(n)运行,而不是 O(n²)时间复杂度。
它还避免了原始type
对象的变异,而是在新创建的数组中创建了新的对象(带有附加属性):
const types = [ { id: 1, name: 'Paint', unit: 'L', }, { id: 2, name: 'Resin', unit: 'mL', }, { id: 3, name: 'Fiberglass', unit: 'yd', } ];
const items = [ { id: 1, type_id: 1, name: 'Brand x paint', qty: 5, }, { id: 2, type_id: 1, name: 'Brand y paint', supplier: 'brand y', qty: 3, }, { id: 3, type_id: 2, name: 'Brand x resin', qty: 5, }, { id: 3, type_id: 2, name: 'Brand y resin', qty: 2, }, { id: 3, type_id: 2, name: 'Brand z resin', qty: 3, }, { id: 3, type_id: 2, name: 'Brand x fiberglass', qty: 7, }, { id: 3, type_id: 2, name: 'Brand y fiberglass', qty: 9, }, ];
// Map keyed by type_id and with the extended type object as value
// (initialised as 0)
const map = new Map(types.map( type => [type.id, {...type, total_qty: 0 }] ));
// Add the quantities from the items to the appropriate map-value
items.forEach(item => map.get(item.type_id).total_qty += item.qty);
// Extract the map values
const itemTypes = Array.from(map.values());
console.log(itemTypes);
答案 1 :(得分:0)
您缺少reduce
中累加器的初始值。
const itemsType = types.map( (type) => {
const temp = items;
type.total_qty = temp
.filter( item => item.type_id === type.id)
.reduce( (acc, item) => acc + item.qty, 0); // value missing here
}
)
答案 2 :(得分:0)
更有效的替代方法是创建具有id的数量的查找对象:
const types = [ { id: 1, unit: 'L', name: 'Paint', }, { id: 2, unit: 'mL', name: 'Resin', }, { id: 3, unit: 'yd', name: 'Fiberglass', } ];
const items = [ { id: 1, type_id: 1, qty: 5, name: 'Brand x paint', }, { id: 2, type_id: 1, qty: 3, name: 'Brand y paint', supplier: 'brand y', }, { id: 3, type_id: 2, qty: 5, name: 'Brand x resin', }, { id: 3, type_id: 2, qty: 2, name: 'Brand y resin', }, { id: 3, type_id: 2, qty: 3, name: 'Brand z resin', }, { id: 3, type_id: 2, qty: 7, name: 'Brand x fiberglass', }, { id: 3, type_id: 2, qty: 9, name: 'Brand y fiberglass', }, ];
const qtys = items.reduce((obj, item) =>
(obj[item.type_id] = (obj[item.type_id] || 0) + item.qty, obj), {})
const itemTypes = types.map(type => ({ ...type, total_qty: qtys[type.id] }))
console.log( JSON.stringify( itemTypes ).replace(/},/g, '},\n ') )
console.log( qtys )
有关对象文字中的扩展语法的信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals