[英]Javascript: Full Outer Join on a Array of Objects, using one key
I have two arrays of objects which I want to "Full Outer Join", like in SQL:我有两个对象数组,我想“完全外连接”,就像在 SQL 中一样:
Dataset A:数据集 A:
[ { id: 1, name: "apple", color: "red" }, {id: 2, name: "banana", color: "yellow"} ]
Dataset B:数据集 B:
[ { id: 1, name: "apple", color: "blue" }, {id: 3, name: "mango", color: "green"} ]
Intended result:预期结果:
[ { id: 1, dataset_a: { id: 1, name: "apple", color: "red" }
, dataset_b: { id: 1, name: "apple", color: "blue" }
}
, { id: 2, dataset_a: { id: 2, name: "banana", color: "yellow"}
, dataset_b: null
}
, { id: 3, dataset_a: null
, dataset_b: { id: 3, name: "mango", color: "green"}
}
]
Instead of null, an empty object would be OK too.而不是 null,一个空对象也可以。 The id's don't necessarily need to be repeated, as shown below.
id不一定要重复,如下图。 So, this would be just as good:
所以,这同样好:
[ { id: 1, dataset_a: { name: "apple", color: "red" }
, dataset_b: { name: "apple", color: "blue" }
}
, { id: 2, dataset_a: { name: "banana", color: "yellow"}
, dataset_b: {}
}
, { id: 3, dataset_a: {}
, dataset_b: { name: "mango", color: "green"}
}
]
Nina Scholtz solution, transformed into aa function: Nina Scholtz 解,转化为 aa 函数:
fullOuterJoin(dataset_a_name, dataset_b_name, dataset_a, dataset_b, key) {
const getNullProperties = keys => Object.fromEntries(keys.map(k => [k, null]));
var data = { [dataset_a_name]:dataset_a, [dataset_b_name]:dataset_b },
result = Object
.entries(data)
.reduce((r, [table, rows]) => {
//forEach dynamic destructuring
rows.forEach(({ [key]:id, ...row }) => {
if (!r[id]) r.items.push(r[id] = { [key]:id, ...getNullProperties(r.tables) });
r[id][table] = row;
});
r.tables.push(table);
r.items.forEach(item => r.tables.forEach(t => item[t] = item[t] || null));
return r;
}, { tables: [], items: [] })
.items;
return result;
},
A code snippet for specifically your need:专门满足您需求的代码片段:
const datasetA = [ { id: 1, name: "apple", color: "red" }, {id: 2, name: "banana", color: "yellow"} ]
const datasetB = [ { id: 1, name: "apple", color: "blue" }, {id: 3, name: "mango", color: "green"} ]
const joined = [];
// datasetA
for (let i = 0; i < datasetA.length; i++) {
let item = {
id: datasetA[i].id,
dataset_a: datasetA[i],
};
joined.push(item);
}
// datasetB
for (let i = 0; i < datasetB.length; i++) {
const foundObject = joined.find(d => d.id === datasetB[i].id);
if (foundObject) {
foundObject['dataset_b'] = datasetB[i];
}
else {
let item = {
id: datasetB[i].id,
dataset_a: {},
dataset_b: datasetB[i],
};
joined.push(item);
}
}
console.log(joined);
You could take a dynamic approach and store the wanted data sets in an object and iterate the entries form the object.您可以采用动态方法并将所需的数据集存储在对象中,然后从对象中迭代条目。 Then group by
id
and get all items back.然后按
id
分组并取回所有项目。
This approach uses an object as hash table with id
as key and an array as storage for the result set.这种方法使用对象作为哈希表,以
id
作为键,使用数组作为结果集的存储。 If an id
is not known, a new object with id
and previously used keys with null
value are used.如果
id
未知,则使用具有id
的新对象和先前使用的具有null
值的键。 Then the actual data set is added to the object.然后将实际数据集添加到对象中。
Finally for missing tables null
values are assigned as well.最后,对于缺少的表,
null
值也被分配。
const getNullProperties = keys => Object.fromEntries(keys.map(k => [k, null])); var dataset_a = [{ id: 1, name: "apple", color: "red" }, { id: 2, name: "banana", color: "yellow" }], dataset_b = [{ id: 1, name: "apple", color: "blue" }, { id: 3, name: "mango", color: "green" }], data = { dataset_a, dataset_b }, result = Object .entries(data) .reduce((r, [table, rows]) => { rows.forEach(({ id, ...row }) => { if (!r[id]) r.items.push(r[id] = { id, ...getNullProperties(r.tables) }); r[id][table] = row; }); r.tables.push(table); r.items.forEach(item => r.tables.forEach(t => item[t] = item[t] || null)); return r; }, { tables: [], items: [] }) .items; console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var array1 = [ { id: 1, name: "apple", color: "red" }, {id: 2, name: "banana", color: "yellow"} ]
var array2 = [ { id: 1, name: "apple", color: "blue" }, {id: 3, name: "mango", color: "green"} ]
var array_sum = array1.concat(array2)
var array_result = []
array_sum.forEach(function(candidate, index){
var obj_id = candidate.id;
delete candidate.id
if(array_result.length == 0){
array_result.push({
"id": obj_id,
["dataset_" + index]: candidate
})
}else{
for(var i=0; i<array_result.length; i++){
if(array_result[i].id == obj_id){
array_result[i]["dataset_" + index] = candidate
break;
}else if(i == array_result.length - 1){
array_result.push({
"id": obj_id,
["dataset_" + index]: candidate
})
}
}
}
})
console.log(array_result)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.