在JavaScript中嵌套数组函数时需要帮助

时间:2018-12-08 16:14:45

标签: javascript arrays object

我有以下两个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属性,那么我愿意提出建议。预先感谢!

3 个答案:

答案 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