[英]Javascript: Merge 2 arrays of objects into a new one, based on object properties
I have 2 arrays of JSON objects in javascript from which I would like to create a new array where I map on the property "Word_No" They look like this:我在 javascript 中有 2 个 arrays 的 JSON 个对象,我想从中创建一个新数组,其中我 map 在属性“Word_No”上 它们看起来像这样:
wordInfo (length 4000): 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"
}
]
and wordTags (length 250):和 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"
}
]
What I need to become is a new array: Alarmlist (length 4000):我需要变成的是一个新数组:Alarmlist(长度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"
}
]
When I try to build this function using 2 for loops and mapping on the the Word_No property, it crashes.当我尝试使用 2 个 for 循环和 Word_No 属性上的映射来构建这个 function 时,它崩溃了。
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);
}
}
When I limit i and j to for example 10, the function executes and shows the word numbers in the debug window.例如,当我将 i 和 j 限制为 10 时,function 将执行并在调试 window 中显示单词编号。
My idea was to map everything like this:我的想法是 map 一切都是这样的:
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);
}
But since the arrays are too big, the Node Red application just crashes.但是由于 arrays 太大,Node Red 应用程序崩溃了。 I'm not sure what would be the efficient way to handle this?
我不确定处理这个问题的有效方法是什么?
I'd suggest first creating a lookup object for OPC_Tag using Array.reduce()
on wordTags - this will improve performance and avoid doing a.find() for each iteration of the loop on wordInfo.我建议首先使用 wordTags 上的
Array.reduce()
为 OPC_Tag 创建一个查找 object - 这将提高性能并避免在 wordInfo 循环的每次迭代中执行 a.find()。
We'd then use Array.map()
on wordInfo to create the final result:然后我们在 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; }
I would suggest to create a Map
for the second array, keyed by Word_No
.我建议为第二个数组创建一个
Map
,由Word_No
键入。 Then map that array to objects where the translation is made with that Map
.然后 map 该数组指向使用该
Map
进行翻译的对象。 With object destructuring this can become quite elegant:使用 object 解构,这会变得非常优雅:
// 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);
for me you can make like this, just using.map() and.filter() method:对我来说,你可以这样做,只需要使用 .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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.