JS合并数组并划分合并的值

时间:2019-05-17 12:16:21

标签: javascript ecmascript-6

我有2个具有唯一键name的数组

const a1 = [  
   {  
      "name":"foo",
      "count":5,
   },
   {  
      "name":"bar",
      "count":0,
   }
]
const a2 = [  
   {  
      "name":"foo",
      "pop":58,
   },
   {  
      "name":"bar",
      "pop":22,
   }
]

然后,我需要创建a3,它具有a1a2的属性,以及第三个属性result,它等于pop/count < / p>

我已经能够在这里合并两个数组:

  const a3 = [a1, a2].reduce((a, b) =>
    a.map((c, i) => Object.assign({}, c, b[i]))
  );

我的预期结果是

a3 = [  
   {  
      "name":"foo",
      "count":5,
      "pop":58,
      "result": 11.6
   },
   {  
      "name":"bar",
      "count":0,
      "pop":22,
      "result": infinity
   }
]

但是,我一直试图在此reduce函数中添加新属性。我查看了许多类似的问题,但是找不到在这种情况下对我有帮助的问题。

4 个答案:

答案 0 :(得分:2)

这里不需要reduce,只需map。由于顺序是相同的,因此只需映射其中一个并从另一个中获取对象,然后进行组合和计算就很简单了:

const a1 = [  
   {  
      "name":"foo",
      "count":5,
   },
   {  
      "name":"bar",
      "count":0,
   }
];
const a2 = [  
   {  
      "name":"foo",
      "pop":58,
   },
   {  
      "name":"bar",
      "pop":22,
   }
];

const result = a1.map((obj1, index) => {
    const obj2 = a2[index];
    //assert: obj1.name === obj2.name
    return {
        name: obj1.name,
        count: obj1.count,
        pop: obj2.pop,
        result: obj2.pop / obj1.count
    };
});

console.log(result);

或者使用destructuring,它虽然更干净,但是在您习惯之前很难遵循:

const a1 = [  
   {  
      "name":"foo",
      "count":5,
   },
   {  
      "name":"bar",
      "count":0,
   }
];
const a2 = [  
   {  
      "name":"foo",
      "pop":58,
   },
   {  
      "name":"bar",
      "pop":22,
   }
];

const result = a1.map(({name, count}, index) => {
    const {name: name2, pop} = a2[index];
    //assert: name === name2
    return {
        name,
        count,
        pop,
        result: pop / count
    };
});

console.log(result);

答案 1 :(得分:0)

如果元素的顺序不同。

const a1 = [  
	{  
		 "name":"foo",
		 "count":5,
	},
	{  
		 "name":"bar",
		 "count":0,
	}
]
const a2 = [  
	{  
		 "name":"foo",
		 "pop":58,
	},
	{  
		 "name":"bar",
		 "pop":22,
	}
]

let out = a1.map(e => {
	let {pop} = a2.find(({name}) => name = e.name);
	return {...e, pop, result: isFinite(pop/e.count)? pop/e.count : 0}
});
console.log(out)

如果元素的顺序相同

const a1 = [  
	{  
		 "name":"foo",
		 "count":5,
	},
	{  
		 "name":"bar",
		 "count":0,
	}
]
const a2 = [  
	{  
		 "name":"foo",
		 "pop":58,
	},
	{  
		 "name":"bar",
		 "pop":22,
	}
]

let out = a1.map((e, i) => {
	let {pop} = a2[i];
	return {...e, pop, result: isFinite(pop/e.count)? pop/e.count : 0}
});
console.log(out)

答案 2 :(得分:0)

尝试一下:

const a3 = [a1, a2].reduce((a, b) =>
       a.map((c, i) => Object.assign({result: b[i].pop/c.count}, c, b[i]))
     );

答案 3 :(得分:0)

不好,但是可以工作。请添加“请勿被零除”

var res = a1.concat(a2).reduce( (acc, v) => {
   acc[v.name] = acc[v.name] || {};
   ['count', 'pop'].filter( k => v[k] !== undefined).forEach( k => acc[v.name][k] = acc[v.name][k] || v[k] );
   return acc;
}, {});

Object.keys(res).forEach( k => res[k].result = res[k].pop / res[k].count);