Javascript:根据对象属性将 2 个对象数组合并为一个新数组
Javascript: Merge 2 arrays of objects into a new one, based on object properties
我在 javascript 中有 2 个 JSON 对象数组,我想从中创建一个新数组,并在其中映射到 属性 “Word_No”
它们看起来像这样:
wordInfo(长度4000):
[
{
"Word_No": "0",
"Alarm_Bit": "0",
"Alarm_No": "1",
"Alarm_Description": "Alarm text 1"
},
{
"Word_No": "0",
"Alarm_Bit": "1",
"Alarm_No": "2",
"Alarm_Description": "Alarm text 2"
},
{
"Word_No": "0",
"Alarm_Bit": "2",
"Alarm_No": "3",
"Alarm_Description": "Alarm text 3"
}
]
和wordTags(长度250):
[
{
"Word_No": "0",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15"
},
{
"Word_No": "1",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31"
},
{
"Word_No": "2",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47"
}
]
我需要变成的是一个新数组:
警报列表(长度 4000):
[
{
"OPC Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15",
"Alarm_Bit": "0",
"Alarm_No": "1",
"Alarm_Description": "Alarm text 1"
},
{
"OPC Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15",
"Alarm_Bit": "1",
"Alarm_No": "2",
"Alarm_Description": "Alarm text 2"
},
{
"OPC Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15",
"Alarm_Bit": "2",
"Alarm_No": "3",
"Alarm_Description": "Alarm text 3"
}
]
当我尝试使用 2 个 for 循环和 Word_No 属性 上的映射构建此函数时,它崩溃了。
for (i = 0; i < wordInfo.length; ++i){ //Outer loop
for (j = 0; j < wordTags.length; ++j){ //Inner loop
msg.Info_Word_No = wordInfo[i].Word_No //Woordnr
msg.Tag_Word_No = wordTags[j].Word_No //Woordnr
node.send(msg);
}
}
当我将 i 和 j 限制为例如 10 时,该函数将执行并在调试中显示单词编号 window。
我的想法是像这样映射所有内容:
if(wordInfo[i].Word_No == wordTags[i].Word_No){
var alarmTagInfo;
alarmTagInfo.Alarm_No=wordInfo[i].Alarm_No;
alarmTagInfo.OPC_Tag = wordTags[i].OPC_Tag;
alarmTagInfo.Alarm_Bit = wordInfo[i].Alarm_Bit;
msg.payload = alarmTagInfo;
alarmlist.push(alarmTagInfo);
}
但是由于数组太大,Node Red 应用程序崩溃了。
我不确定处理此问题的有效方法是什么?
我建议首先使用 wordTags 上的 Array.reduce()
为 OPC_Tag 创建一个查找对象 - 这将提高性能并避免在 wordInfo 循环的每次迭代中执行 .find()。
然后我们将在 wordInfo 上使用 Array.map()
来创建最终结果:
let wordInfo = [ { "Word_No": "0", "Alarm_Bit": "0", "Alarm_No": "1", "Alarm_Description": "Alarm text 1" }, { "Word_No": "0", "Alarm_Bit": "1", "Alarm_No": "2", "Alarm_Description": "Alarm text 2" }, { "Word_No": "0", "Alarm_Bit": "2", "Alarm_No": "3", "Alarm_Description": "Alarm text 3" } ]
let wordTags = [ { "Word_No": "0", "OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15" }, { "Word_No": "1", "OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31" }, { "Word_No": "2", "OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47" } ]
// Create a lookup, mapping Word_No to OPC_Tag
let wordTagsLookup = wordTags.reduce((acc, { Word_No, OPC_Tag }) => {
acc[Word_No] = OPC_Tag;
return acc;
}, {})
let result = wordInfo.map(({ Word_No, Alarm_Bit, Alarm_No, Alarm_Description}) => {
return { Alarm_Bit, Alarm_No, Alarm_Description, OPC_Tag: wordTagsLookup[Word_No] };
})
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
我建议为第二个数组创建一个 Map
,以 Word_No
为键。然后将该数组映射到使用该 Map
进行翻译的对象。通过对象解构,这可以变得非常优雅:
// Sample input data
const wordInfo = [{"Word_No": "0","Alarm_Bit": "0","Alarm_No": "1","Alarm_Description": "Alarm text 1"},{"Word_No": "0","Alarm_Bit": "1","Alarm_No": "2","Alarm_Description": "Alarm text 2"},{"Word_No": "0","Alarm_Bit": "2","Alarm_No": "3","Alarm_Description": "Alarm text 3"}];
const wordTags = [{"Word_No": "0","OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15"},{"Word_No": "1","OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31"},{"Word_No": "2","OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47"}];
// Create map keyed by Word_No:
const map = new Map(wordTags.map(({Word_No, OPC_Tag}) => ([Word_No, OPC_Tag])));
// Translate the source data to the target data
const alarmList = wordInfo .map(({Word_No, ...rest}) =>
({OPC_Tag: map.get(Word_No), ...rest})
);
console.log(alarmList);
对我来说,你可以像这样制作,只需使用 .map() 和 .filter() 方法:
const wordInfo = [
{
"Word_No": "0",
"Alarm_Bit": "0",
"Alarm_No": "1",
"Alarm_Description": "Alarm text 1"
},
{
"Word_No": "0",
"Alarm_Bit": "1",
"Alarm_No": "2",
"Alarm_Description": "Alarm text 2"
},
{
"Word_No": "0",
"Alarm_Bit": "2",
"Alarm_No": "3",
"Alarm_Description": "Alarm text 3"
},
];
const wordTags = [
{
"Word_No": "0",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15"
},
{
"Word_No": "1",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31"
},
{
"Word_No": "2",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47"
}
];
const data = wordInfo.map((wordInfoItem) => {
const wordTag = wordTags
.filter((wordTagItem) => (wordInfoItem["Word_No"] === wordTagItem["Word_No"]))[0];
const newArray = {
...wordTag,
...wordInfoItem,
};
delete newArray['Word_No'];
return newArray;
});
console.log(data);
我在 javascript 中有 2 个 JSON 对象数组,我想从中创建一个新数组,并在其中映射到 属性 “Word_No” 它们看起来像这样:
wordInfo(长度4000):
[
{
"Word_No": "0",
"Alarm_Bit": "0",
"Alarm_No": "1",
"Alarm_Description": "Alarm text 1"
},
{
"Word_No": "0",
"Alarm_Bit": "1",
"Alarm_No": "2",
"Alarm_Description": "Alarm text 2"
},
{
"Word_No": "0",
"Alarm_Bit": "2",
"Alarm_No": "3",
"Alarm_Description": "Alarm text 3"
}
]
和wordTags(长度250):
[
{
"Word_No": "0",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15"
},
{
"Word_No": "1",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31"
},
{
"Word_No": "2",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47"
}
]
我需要变成的是一个新数组: 警报列表(长度 4000):
[
{
"OPC Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15",
"Alarm_Bit": "0",
"Alarm_No": "1",
"Alarm_Description": "Alarm text 1"
},
{
"OPC Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15",
"Alarm_Bit": "1",
"Alarm_No": "2",
"Alarm_Description": "Alarm text 2"
},
{
"OPC Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15",
"Alarm_Bit": "2",
"Alarm_No": "3",
"Alarm_Description": "Alarm text 3"
}
]
当我尝试使用 2 个 for 循环和 Word_No 属性 上的映射构建此函数时,它崩溃了。
for (i = 0; i < wordInfo.length; ++i){ //Outer loop
for (j = 0; j < wordTags.length; ++j){ //Inner loop
msg.Info_Word_No = wordInfo[i].Word_No //Woordnr
msg.Tag_Word_No = wordTags[j].Word_No //Woordnr
node.send(msg);
}
}
当我将 i 和 j 限制为例如 10 时,该函数将执行并在调试中显示单词编号 window。
我的想法是像这样映射所有内容:
if(wordInfo[i].Word_No == wordTags[i].Word_No){
var alarmTagInfo;
alarmTagInfo.Alarm_No=wordInfo[i].Alarm_No;
alarmTagInfo.OPC_Tag = wordTags[i].OPC_Tag;
alarmTagInfo.Alarm_Bit = wordInfo[i].Alarm_Bit;
msg.payload = alarmTagInfo;
alarmlist.push(alarmTagInfo);
}
但是由于数组太大,Node Red 应用程序崩溃了。 我不确定处理此问题的有效方法是什么?
我建议首先使用 wordTags 上的 Array.reduce()
为 OPC_Tag 创建一个查找对象 - 这将提高性能并避免在 wordInfo 循环的每次迭代中执行 .find()。
然后我们将在 wordInfo 上使用 Array.map()
来创建最终结果:
let wordInfo = [ { "Word_No": "0", "Alarm_Bit": "0", "Alarm_No": "1", "Alarm_Description": "Alarm text 1" }, { "Word_No": "0", "Alarm_Bit": "1", "Alarm_No": "2", "Alarm_Description": "Alarm text 2" }, { "Word_No": "0", "Alarm_Bit": "2", "Alarm_No": "3", "Alarm_Description": "Alarm text 3" } ]
let wordTags = [ { "Word_No": "0", "OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15" }, { "Word_No": "1", "OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31" }, { "Word_No": "2", "OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47" } ]
// Create a lookup, mapping Word_No to OPC_Tag
let wordTagsLookup = wordTags.reduce((acc, { Word_No, OPC_Tag }) => {
acc[Word_No] = OPC_Tag;
return acc;
}, {})
let result = wordInfo.map(({ Word_No, Alarm_Bit, Alarm_No, Alarm_Description}) => {
return { Alarm_Bit, Alarm_No, Alarm_Description, OPC_Tag: wordTagsLookup[Word_No] };
})
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
我建议为第二个数组创建一个 Map
,以 Word_No
为键。然后将该数组映射到使用该 Map
进行翻译的对象。通过对象解构,这可以变得非常优雅:
// Sample input data
const wordInfo = [{"Word_No": "0","Alarm_Bit": "0","Alarm_No": "1","Alarm_Description": "Alarm text 1"},{"Word_No": "0","Alarm_Bit": "1","Alarm_No": "2","Alarm_Description": "Alarm text 2"},{"Word_No": "0","Alarm_Bit": "2","Alarm_No": "3","Alarm_Description": "Alarm text 3"}];
const wordTags = [{"Word_No": "0","OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15"},{"Word_No": "1","OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31"},{"Word_No": "2","OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47"}];
// Create map keyed by Word_No:
const map = new Map(wordTags.map(({Word_No, OPC_Tag}) => ([Word_No, OPC_Tag])));
// Translate the source data to the target data
const alarmList = wordInfo .map(({Word_No, ...rest}) =>
({OPC_Tag: map.get(Word_No), ...rest})
);
console.log(alarmList);
对我来说,你可以像这样制作,只需使用 .map() 和 .filter() 方法:
const wordInfo = [
{
"Word_No": "0",
"Alarm_Bit": "0",
"Alarm_No": "1",
"Alarm_Description": "Alarm text 1"
},
{
"Word_No": "0",
"Alarm_Bit": "1",
"Alarm_No": "2",
"Alarm_Description": "Alarm text 2"
},
{
"Word_No": "0",
"Alarm_Bit": "2",
"Alarm_No": "3",
"Alarm_Description": "Alarm text 3"
},
];
const wordTags = [
{
"Word_No": "0",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm0_15"
},
{
"Word_No": "1",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm16_31"
},
{
"Word_No": "2",
"OPC_Tag": "HH.Application.TmpHmi_Var.TmpHmiC7.Alarm32_47"
}
];
const data = wordInfo.map((wordInfoItem) => {
const wordTag = wordTags
.filter((wordTagItem) => (wordInfoItem["Word_No"] === wordTagItem["Word_No"]))[0];
const newArray = {
...wordTag,
...wordInfoItem,
};
delete newArray['Word_No'];
return newArray;
});
console.log(data);