javascript - 根据匹配的 ID 合并两个数组中的项目
问题描述
我有一个这样的数据对象:
{
"data1": [
[
"ID",
"name",
"Birthday"
],
[
"10",
"thomas",
"1992-03-17"
],
[
"11",
"Emily",
"2000-03-03"
]
],
"data2": [
[
"Balance",
"ID"
],
[
"$4500",
"10"
],
[
"$1500",
"13"
]
]
}
它包含两个数组data1
和data2
. 每个数组中的第一行是列的名称,其余行包含数据(将其视为表格)。
我想比较ID
两个数组中的字段,如果ID
s 匹配,则最终输出将包含一列Balance
,其中余额对应于该列ID
,如果ID
s 不匹配,Balance
则将是$0
。
预期输出:
{
"output": [
[
"ID",
"name",
"Birthday",
"Balance"
],
[
"10",
"thomas",
"1992-03-17",
"$4500" //ID 10 matched so the balance added here
],
[
"11",
"Emily",
"2000-03-03",
"0" //0 bcoz the ID 11 is not there in data2 array
]
]
}
我觉得这很难完成。把它想象成 MySQL 中的 LEFT-JOIN。我提到了这个解决方案,但它在我的情况下不起作用,因为我的回复中没有密钥。
编辑:我也需要加入其他领域。
解决方案
您可以使用Array.prototype.map()、find、filter、slice、reduce、concat、includes和Object.assign()。
这个解决方案:
- 处理项目的任意顺序。订单从标题中读取。
Balance
仅当 中存在一个字段时才附加一个字段data2
。- 加入所有其他领域(由 OP 要求,请参阅下面的评论)。
data1
如果数据不存在于和中,则将默认值作为输入并使用它们data2
。
function merge({ data1, data2 }, defaults) {
// get the final headers, add/move 'Balance' to the end
const headers = [...data1[0].filter(x => x !== 'Balance')]
.concat(data2[0].includes('Balance') ? ['Balance'] : []);
// map the data from data1 to an array of objects, each key is the header name, also merge the default values.
const d1 = data1.slice(1)
.map(x => x.reduce((acc, y, i) => ({ ...defaults, ...acc, [data1[0][i]]: y }), {}));
// map the data from data2 to an array of objects, each key is the header name
const d2 = data2.slice(1)
.map(x => x.reduce((acc, y, i) => ({ ...acc, [data2[0][i]]: y }), {}));
// combine d1 and d2
const output = d1.map((x, i) => { // iterate over d1
// merge values from d2 into this value
const d = Object.assign(x, d2.find(y => y['ID'] === x['ID']));
// return an array ordered according to the header
return headers.map(h => d[h]);
});
return { output: [headers, ...output] };
}
const test0 = {
data1: [[ "ID","name","Birthday","other"],["10","thomas","1992-03-17","empty"],["11","Emily","2000-03-03","empty"]],
data2: [["other", "ID", "Balance", "city"],["hello", "10", "$4500", "New York"],["world", "10","$8","Brazil"]]
};
const test1 = {
data1: [["ID","name","Birthday"],["10","thomas","1992-03-17"],["11","Emily","2000-03-03"]],
data2: [["other","ID"],["x","10"],["y","11"]]
};
console.log(merge(test0, { Balance: '$0' }));
console.log(merge(test1, { Balance: '$0' }));
推荐阅读
- github-api - GitHub-Actions: 创建 GitHub-Release 草稿时触发
- jquery - Datatables 服务器端在 localhost 上工作正常,但在 Godaddy 上托管后出现以下错误
- webpack - node-sass 未应用来自 node_modules 的样式
- php - 我还想在父类别中显示子类别的产品
- asp.net-core - AzureAD 客户端密码在 dotnetcore 应用程序中已过期 - 错误代码:AADSTS7000222 - 如何更新?
- c# - 在 asp.net 中授权角色
- ubuntu - 如何在 VSCode 中更改光标?
- javascript - 当您将鼠标悬停在甜甜圈的左/右上方时,Chart.js 甜甜圈图未显示工具提示
- ios - 在 iOS GCD 中调用 DispatchQueue.main.async 的成本
- opengl-es - glsl 可以支持的最大整数(无符号整数)值是多少?