What is the best way in nodejs to compare two different array of objects based on one or more attributes/fields? The fields name can be different - node.js

let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
let output = [];
obj1.map(o1 => {
for (let i=0;i<obj2.length;i++) {
if (o1.field1 === obj2[i].attribute1) {
output.push(Object.assign(obj2[i], o1));
obj2.splice(i,1);
break;
}
}
});
console.log(output); //*[{attribute1:11,attribute2:12,field1:11,field2:12,field3:13},{attribute1:21,attribute2:22,field1:21,field2:22,field3:23},{attribute1:31,attribute2:32,field1:31,field2:32,field3:33}]*
The above code compares two different objects with its fields.
Here I am using 2 loops.
So my question is, do we have any better approach to achieve the same? Without two loops or using any package or the best way

You can use find to find the first element where the statement is true instead of looping and manually checking if the statement is true or false. Sadly find is also an iterative method but I don't see any other way to improve this. I am using filter to remove the elements that don't fulfil the condition o2.attribute1 === o1.field1.
let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
const output = obj1.map(o1 => {
let obj2Value = obj2.find(o2 => o2.attribute1 === o1.field1);
return obj2Value ? Object.assign(obj2Value, o1) : null;
}).filter(o => o !== null);
console.log(output);
Alternatively you can use forEach to do this:
let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
let output = [];
obj1.forEach(o1 => {
let obj2Value = obj2.find(o2 => o2.attribute1 === o1.field1);
obj2Value ? output.push(Object.assign(obj2Value, o1)) : '';
});
console.log(output);
There are several approaches to achieve this. Also remember map already returns a new array so no need to use push inside, just return. Check this for better understanding:
https://stackoverflow.com/questions/34426458/javascript-difference-between-foreach-and-map#:~:text=forEach%20%E2%80%9Cexecutes%20a%20provided%20function,every%20element%20in%20this%20array.%E2%80%9D .

Related

Best way to search march in an array of JavaScript Objects?

I'm facing a challenge to match values within an array of JS objects. Let me give you an example,
var dynamicObjectArray = [
{Id: 1422859025, FromTime: "2023-02-12T19:00:00Z", ToTime: "2023-02-12T20:00:00Z"},
{Id: 1422859027, FromTime: "2023-02-12T18:00:00Z", ToTime: "2023-02-12T19:00:00Z"}
]
I need to find all Ids for FromTime or ToTime match with "2023-02-12T19:00:00Z"
Using a database, it can be done easily. But, here, I need to play an array of 100 objects max. Also, data will be dynamic. Can you please suggest me a way to achieve the goal using NodeJS.
You could use the JS Date builtin constructor to compare dates instead of using the string directly.
Filter your matching objects, and map the ids.
You can do something like this.
const dynamicObjectArray = [{
Id: 1422859025,
FromTime: "2023-02-12T19:00:00Z",
ToTime: "2023-02-12T20:00:00Z"
},
{
Id: 1422859027,
FromTime: "2023-02-12T18:00:00Z",
ToTime: "2023-02-12T19:00:00Z"
}
];
const matchTime = new Date("2023-02-12T19:00:00Z").getTime();
const matchIds = dynamicObjectArray.filter(obj => {
const fromTime = new Date(obj.FromTime).getTime();
const toTime = new Date(obj.ToTime).getTime();
return matchTime === fromTime || matchTime === toTime;
}).map(obj => obj.Id);
console.log(matchIds);
If you want a suggestion, you can do something like this:
Create a function that takes as a parameter, the wanted Date
Create a variable containing an array where you will save all those "id's" that match your condition
Create a for loop
Create an if condition, that matches the following condition:
if date exists on "FromTime" or exists on "ToTime", push to your "id's array"
Return your ids array
Here is the code implementation:
function filterObjByDate(TO_MATCH_DATE) {
let ids = [];
for (let i = 0; i < dynamicObjectArray.length; i++) {
if (
dynamicObjectArray[i].FromTime === TO_MATCH_DATE ||
dynamicObjectArray[i].ToTime === TO_MATCH_DATE
) {
ids.push(dynamicObjectArray[i].Id);
}
}
return ids
}
That's it. If you have more question, ask me 😀👍

How to add Numbers In Arrays format if we have a word in 3 files using nodejs

I want to ask a question, what is it, I have three files, if there is a Word COMMON in those files then it should be printed like this [1,2 3], otherwise, if there is a word in 1 and 2 then it should be printed like this [1 2] , I Tried to PUSH ARRAY but it's not happening
Here Is My Code:
let Page1data = filtered.map((val) => {
let data = {};
if (Page1.includes(val)) {
data[val] = ["1"];
}
if (Page2.includes(val)) {
data[val] = ["2"];
}
if (Page3.includes(val)) {
data[val] = ["3"];
}
return data;
});
console.log(Page1data);
If I get it right, the problem is with your declaration.
.push() is for arrays not for objects. You have declared your data variable as an object.
You should use:
let data = [];
instead of
let data = {};
So it's going to look like this:
let data = [];
if (Page1.includes(val)) {
data.push("1");
}
etc...

Merge json array object to itself

would like to ask, how to merge in nodejs
[ {"id":"1234","pick1":"Heart","isHit1":false},{"id":"2345","pick1":"Spade","isHit1":false},{"id":"1234","pick2":"Diamond","isHit2":false},{"id":"2345","pick2":"Clubs","isHit2":false} ]
To this
[{"id":"1234","pick1":"Heart","isHit1":false,"pick2":"Diamond","isHit2":false}, {"id":"2345","pick1":"Spade","isHit1":false,"pick2":"Clubs","isHit2":false}]
What i've tried is, doing a for loop, but, it takes a while, cause i'm processing around 100 data.
Update:
Already found a shorthand for this, thank you!
Solution:
let result = json1.map(obj => {
let data = json1.find(item => item.id === obj.id);
return {...obj, ...data}
});
Processing wise this one is fastest solution, it just loops n times [we can say O(n) complexity]:
let dict = {};
for (let i = 0; i < a.length; i++) {
dict[a[i].id] = {...dict[a[i].id], ...a[i]};
}
let output = [];
for (key of Object.keys(dict)) {
output.push(dict[key]);
}
console.log(output);

Verify and select the right object in an array thanks to a find method which will match with a param json

I need some help,
I've got a json with some parameters inside of it, actually 2 but one day we may add some more in it.
I want to find between some object in an array the right one thanks to all parameters in the json
Am i using the right method ?
to be clearer, i want the param.t to match with the element.t, and the param.tid to match with the element.tid and if moving forward one more parameter cd1 is added to the JSON, this param.cd1 will match with element.cd1
thanks for the time !
const array1 = [{"t":"pageview","de":"UTF-8","tid":"UA-xxxxxxxxxx-17","cd1":"Without cookie"},{"t":"timing","de":"UTF-8","tid":"UA-xxxxxxxx-1","cd1":"France"}];
const param = { t: 'pageview', tid: 'UA-xxxxxxxxxx-17' }
for (let [key, value] of Object.entries(param)) {
console.log(`${key}: ${value}`);
}
const obj = array1.find(element => element.t == param.t);
If I am following correctly, you want to compare an array of objects to an object and based on some keys in 'param' object you want to filter out your array1.
const array2 = [{"t":"pageview","de":"UTF-8","tid":"UA-xxxxxxxxxx-17","cd1":"Without cookie"},{"t":"timing","de":"UTF-8","tid":"UA-xxxxxxxx-1","cd1":"France"}];
const param1 = { t: 'pageview', tid: 'UA-xxxxxxxxxx-17' }
const test = array2.find(checkExist);
const checkExist = el => {
return el.t == param1.t && el.tid == param1.tid; // here you can add your keys in future
}

How to remove same named objects from a JSON structure, but with a non uniform pattern in structure?

I have a json structure, that is a bit odd, this is returned from a remote device, and I have to accept it as is. For example...
{"_":"e6a7f749","4321013c":{"_":"5d839a60"},"67ea44a0":{"_":"ec7500f9"},"6bea5f08":{"_":"ecdaead4"},"1e92311e":{"_":"5348dab3"}}
I need to remove the '_' key-value pairs, but retain everything else, such that...
{"4321013c":,"67ea44a0":,"6bea5f08":,"1e92311e":,}
As you can see, this leaves just some 'keys', from the original structure. I then want to convert the 'keys' to a simple array of values. Such...
["4321013c","67ea44a0","6bea5f08","1e92311e"]
All this done in node.js (JavaScript) by the way.
Here is my solution. I am not sure if I fully understood the question though.
But here I traverse the object, an gather up all the keys and values into another, flattened object. Then finally, I run Object.keys on that and remove any "_" values.
const obj = {
"_":"e6a7f749",
"4321013c":{"_":"5d839a60"},
"67ea44a0":{"_":"ec7500f9"},
"6bea5f08":{"_":"ecdaead4"},
"1e92311e":{"_":"5348dab3"}
};
const collectValues = (root) => {
return Object.keys(root).reduce((map, key) => {
const value = root[key];
if (typeof value === 'string') {
map = {
...map,
[key]: true,
[value]: true
};
} else {
const nestedValues = collectValues(root[key]);
map = {
...map,
...nestedValues,
[key]: true
};
}
return map;
}, {});
}
const uniqueArray = Object.keys(collectValues(obj)).filter(v => v !== '_');
console.log(uniqueArray);

Resources