Also, the filter passes every other item in list2 which should be matched in list1. Meaning (as that sentence probably did not make sense):
list1.map list2.filter id:1 [id:3,id:2,id:1] ^-match id:2 [id:3,id:2,id:1] ^-match id:3 [id:3,id:2,id:1] ^-match
Ideally on the first iteration of map (
list1 id:1
), when the filter encounterslist2 id:3
(first item) it would just match it tolist1 id:3
根据上述概念(当稍后遇到时匹配到较早的ID),我想出了version2
。
这将list2转换为字典,然后通过键在任何序列中查找值。
const list1 = [
{id: '1',init:'init1'},
{id: '2',init:'init2'},
{id: '3',init:'init3'}
];
const list2 = [
{id: '2',data:'data2'},
{id: '3',data:'data3'},
{id: '4',data:'data4'}
];
/* ---------
* version 1
*/
const mergedV1 = list1.map(n => (
{...n,...list2.filter(f => f.id===n.id)[0]}
));
/* [
{"id": "1", "init": "init1"},
{"id": "2", "init": "init2", "data": "data2"},
{"id": "3", "init": "init3", "data": "data3"}
] */
/* ---------
* version 2
*/
const dictList2 = list2.reduce((dict,item) => (dict[item.id]=item,dict),{});
// does not handle duplicate ids but I think that's
// outside the context of this question.
const mergedV2 = list1.map(n => ({...n,...dictList2[n.id]}));
/* [
{"id": "1", "init": "init1"},
{"id": "2", "init": "init2", "data": "data2"},
{"id": "3", "init": "init3", "data": "data3"}
] */
JSON.stringify(mergedV1) === JSON.stringify(mergedV2);
// true
// and just for fun
const sqlLeftOuterJoinInJS = list1 => list2 => on => {
const dict = list2.reduce((dict,item) => (
dict[item[on]]=item,dict
),{});
return list1.map(n => ({...n,...dict[n[on]]}
))};
显然,以上示例非常简单(合并两个列表,每个列表的长度为3)。我正在处理更复杂的情况。
我不知道是否有一些更聪明(理想情况下是功能性的)的技术可以使用。