[英]Join arrays of objects on a mutiple key in Javascript
I have two arrays of objects: 我有两个对象数组:
A = [
{ id1: "1", id2: "a", p1: "3", p2: "4" },
{ id1: "1", id2: "b", p1: "5", p2: "6" },
{ id1: "2", id2: "a", p1: "7", p2: "8" },
{ id1: "2", id2: "b", p1: "9", p2: "10" }
];
B = [
{ id1: "1", id2: "a", p3: "13", p4: "14" },
{ id1: "1", id2: "b", p3: "15", p4: "16" },
{ id1: "2", id2: "a", p3: "17", p4: "18" },
{ id1: "2", id2: "b", p3: "19", p4: "20" }
];
I need a function that makes an inner join between the two objects based on the two properties id1
and id2
, making a union of the other properties ( properties names are never equal except for id1
and id2
) In other words I need as a result: 我需要一个函数,该函数基于两个属性
id1
和id2
在两个对象之间进行内部id1
并id2
其他属性( 除了id1
和id2
属性名称永远不会相等 )换句话说,我需要:
C = [
{ id1: "1", id2: "a", p1: "3", p2: "4", p3: "13", p4: "14" },
{ id1: "1", id2: "b", p1: "5", p2: "6", p3: "15", p4: "16" },
{ id1: "2", id2: "a", p1: "7", p2: "8", p3: "17", p4: "18" },
{ id1: "2", id2: "b", p1: "9", p2: "10", p3: "19", p4: "20" }
];
In here I can find a way to make the join using one single key. 在这里,我可以找到一种使用一个键进行联接的方法。 I need an extention for the multiple keys case.
我需要扩展多个键的情况。
http://learnjsdata.com/combine_data.html http://learnjsdata.com/combine_data.html
You can make a lookup based on one array with a composite key from the two ids, then loop through the second, look up the merged key, and create a new object from the two items using Object.assign()
. 您可以使用两个ID中的复合键基于一个数组进行查找,然后遍历第二个,查找合并的键,并使用
Object.assign()
从这两个项中创建一个新对象。 This will allow you to make the list without having an O(n²) solution of searching A
for every item in B
这样您就可以列出列表,而无需O(n²)解决方案来搜索
A
中的每个项目的B
let A=[ {id1:"1", id2:"a", p1:"3", p2:"4"}, {id1:"1", id2:"b", p1:"5", p2:"6"}, {id1:"2", id2:"a", p1:"7", p2:"8"}, {id1:"2", id2:"b", p1:"9", p2:"10"} ] let B=[{id1:"1", id2:"a", p3:"13", p4:"14"}, {id1:"1", id2:"b", p3:"15", p4:"16"}, {id1:"2", id2:"a", p3:"17", p4:"18"}, {id1:"2", id2:"b", p3:"19", p4:"20"} ] let lookup = A.reduce((obj, item) => { obj[`${item.id1}_${item.id2}`] = item // key in form of id1_id2 return obj }, {}) let merged = B.reduce((arr, item) => { if (lookup[`${item.id1}_${item.id2}`]) { arr.push(Object.assign({}, lookup[`${item.id1}_${item.id2}`], item)) } return arr }, []) console.log(merged)
You just need to make sure the separator of the key ( _
here) doesn't exist in you ids. 您只需要确保ID中不存在键的分隔符(此处为
_
)即可。 If that's a problem, you could make a nested object with lookups like obj[id1][id2]
: 如果这是一个问题,则可以使用
obj[id1][id2]
类的查询来创建嵌套对象:
let lookup = A.reduce((obj, item) => {
if (!obj[item.id1]) obj[item.id1] = {}
obj[item.id1][item.id2] = item
return obj
}, {} )
and adjust the reduce()
callback to fit. 并调整
reduce()
回调以适合。
If the array's are very large, using a lookup like @MarkMeyer shows would might be better option.
如果数组是非常大的,使用查找类似@MarkMeyer节目
将 可能是更好的选择。 But for smaller arrays doing a simple map, array spread & find works fine. 但是对于较小的数组做一个简单的映射,数组散布和查找工作正常。
As pointed out by @user11299053 this is not the equivalent of an inner join, maybe a left join instead,.. So I'll leave this as is, it might be useful.
正如@ user11299053所指出的,这不等效于内部联接,而可能等效于左联接。.因此,我将其保留不变,这可能会很有用。 :)
:)
const A=[ {id1:"1", id2:"a", p1:"3", p2:"4"}, {id1:"1", id2:"b", p1:"5", p2:"6"}, {id1:"2", id2:"a", p1:"7", p2:"8"}, {id1:"2", id2:"b", p1:"9", p2:"10"} ]; const B=[ {id1:"1", id2:"a", p3:"13", p4:"14"}, {id1:"1", id2:"b", p3:"15", p4:"16"}, {id1:"2", id2:"a", p3:"17", p4:"18"}, {id1:"2", id2:"b", p3:"19", p4:"20"} ]; const merged = B.map(item => ({ ...A.find( f => f.id1 === item.id1 && f.id2 === item.id2), ...item })); console.log(merged);
Both provided answers DO NOT deliver expected result ( inner join which is supposed to contain only matching items from both data sets). 提供的两个答案均未提供预期的结果( 内部联接应该只包含两个数据集中的匹配项)。
I have somewhat extended input arrays in order to demonstrate the difference of output for provided answers and mine: 我有一些扩展的输入数组,以演示提供的答案和我的输出的区别:
const A = [ {id1:"1", id2:"a", p1:"3", p2:"4"}, {id1:"1", id2:"b", p1:"5", p2:"6"}, {id1:"2", id2:"a", p1:"7", p2:"8"}, {id1:"2", id2:"b", p1:"9", p2:"10"}, {id1:"3", id2:"c", p1:"1", p2:"3"} ]; const B = [ {id1:"1", id2:"a", p3:"13", p4:"14"}, {id1:"1", id2:"b", p3:"15", p4:"16"}, {id1:"2", id2:"a", p3:"17", p4:"18"}, {id1:"2", id2:"b", p3:"19", p4:"20"}, {id1:"4", id2:"k", p3:"11", p4:"13"} ]; const innerJoined = A.reduce((result, itemA) => { const itemB = B.find(itemB => itemB.id1 == itemA.id1 && itemB.id2 == itemA.id2); if(itemB) result.push({...itemA, ...itemB}); return result; }, []); console.log(innerJoined);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.