Best way to search march in an array of JavaScript Objects? - node.js

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 😀👍

Related

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

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 .

Get Date from Nested Array of Objects and set that date as an Key in Node.js

I'm using Node.js I have data like this:
const data= [
{"id":"1","date":"2022-09-07T15:56:32.279Z","req_id":"98"},
{"id":"2","date":"2022-09-08T15:48:19.075Z","req_id":"97"},
{"id":"3","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
{"id":"4","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
]
I want data in this format:
expected Output:
"2022-09-06":[
{"id":"4","date":"2022-09-06T15:48:19.073Z","req_id":"96"},
{"id":"3","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
]
"2022-09-08":[
{"id":"2","date":"2022-09-08T15:48:19.075Z","req_id":"97"}
]
"2022-09-07":[
{"id":"1","date":"2022-09-07T15:56:32.279Z","req_id":"98"}
]
Assuming the dates are always in the same format, I would do something like this:
function mapData(data){
// returns the given date as an string in the "%dd-%mm-%yyyy" format
const getDateWithoutTime = (dateString) => dateString.split("T")[0];
const mappedData = [];
for(const req of data){
const formattedDate = getDateWithoutTime(req.date);
// if the key already exists in the array, we add a new item
if(mappedData[formattedDate]) mappedData[formattedDate].push(req);
// if the key doesn't exist, we create an array with that single item for that key
else mappedData[formattedDate] = [req];
}
return mappedData;
}
Straightforward solution using regex:
let result = new Map();
for (const item of data) {
let date = item['date'].match(/\d{4}-\d{2}-\d{2}/)[0];
let items = result.get(date) || [];
items.push(item);
result.set(date, items)
}

How to return the array after altering it back into json format?

I am making a discord bot where you can use the command tcp freeitem to obtain your free item.
I am trying to alter that value of an Account by adding a new item object into the account. When I map the array to replace a value, it erases the name (allAccounts) of the array of the json. More information below. Here is what I have:
const listOfAllItemNames = require(`C:/Users///censored///OneDrive/Desktop/discord bot/itemsDataList.json`)
const accountList = require(`C:/Users///censored///OneDrive/Desktop/discord bot/account.json`)
const fs = require('fs')
var accountThatWantsFreeItem = accountList.allAccounts.find(user => message.author.id === user.userId);
var randomFreeItem = listOfAllItemNames.allItems[Math.floor(Math.random() * listOfAllItemNames.allItems.length)]
if(accountThatWantsFreeItem === undefined) {message.reply('You need to make an account with tcp create!'); return; }
if(accountThatWantsFreeItem.freeItem === true) {message.reply('You already got your free one item!'); return;}
fs.readFile('C:/Users///censored///OneDrive/Desktop/discord bot/account.json', 'utf8', function readFileCallback(err,data) {
if(err){
console.error(err)
} else {
var accountsArray = JSON.parse(data)
console.log(accountsArray)
var whoSentCommand = accountsArray.allAccounts.find(user => message.author.id === user.userId)
whoSentCommand.Items.push(randomFreeItem)
whoSentCommand.freeItem = true;
var test = accountsArray.allAccounts.map(obj => whoSentCommand === obj.id || obj)
//I believe the issue is trying to map it returns a new array
console.log(test)
test = JSON.stringify(test, null, 5)
//fs.writeFile('C:/Users///censored///OneDrive/Desktop/discord bot/account.json', test, err =>{ console.error(err)} )
}
})
when I write the file back to json file, it removes the "allAccounts" identifier in this file
//json file
//array name "allAccounts" is removed, I need this still here for code to work
{
"allAccounts" : [
{
"userId": "182326315813306368",
"username": "serendipity",
"balanceInHand": 0,
"balanceInBank": 0,
"freeItem": false,
"Items": []
},
(No "allAccounts" array name)
to this: output after writing file
So, the final question is
How would I alter the array so that I only alter the account I want without editing the array name?
Please feel free to ask any questions if I was unclear.
Array.map() method returns the converted array.
So in the below line, map() method takes allAccounts array and perform actions and put the target array (not object) to the test variable.
var test = accountsArray.allAccounts.map(obj => whoSentCommand === obj.id || obj)
So for making code works, please change the code like this:
var test = {
"accountsArray": accountsArray.allAccounts.map(obj => whoSentCommand === obj.id || obj)
}
When posting questions, please please reduce the code to a minimal example that will demonstrate the problem, and use words, not code, to describe the problem.
It looks like you are expecting .map to do something other than what it does.
Please consult the documentation for Array.map().
It takes the array that you pass it (in this case accountsArray.allAccounts) and transforms it, returning the transformed array.
You have essentially done test = accountsArray.allAccounts but for some reason are expecting test to contain an Object with the key allAccounts, when in fact it will only contain an Array, because that is what you have assigned it.

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
}

Using Node.js iterating array of object and if value matched then insert all related values in different array

INPUT
[
{"Id":1,"text":"Welcome","question":"san","translation":"willkommen."},
{"Id":1,"text":"Welcome","question":"se","translation":"bienvenida"},
{"Id":1,"text":"Welcome","question":"fr","translation":"propriétaires"},
{"Id":1,"text":"ajax","question":"san","translation":"ommen."},
{"Id":1,"text":"ajax","question":"se","translation":"bienve"},
{"Id":1,"text":"ajax","question":"fr","translation":"propires"}
]
if question = san then all "san" objects will be inserted in array like and so on-
san:[{"text":"Welcome","question":"san","translation":"willkommen.},
{"text":"ajax","question":"san","translation":"ommen."},
se:[{"text":"Welcome","question":"se","translation":"bienvenida.},
{"text":"ajax","question":"se","translation":"bienve."},
fr:[{"text":"Welcome","question":"fr","translation":"propriétaires.},
{"text":"ajax","question":"fr","translation":"propires."},
Question is how do i check if question=san then make one array and insert all san values in it and so on without hardcoding the question property values.
Tried looping things but how to match without hardcoding because in future question attribute can change .
question="san" will be all together in an array "se" will be all together in an array and so on.
New to this not know much about nodejs.
Tried something like this but not coming as required way
fs.readFile('./data.json', 'utf8', function (err,data) {
data = JSON.parse(data);
var array = [];
for(var i = 0; i < data.length; i++) {
var lang = data[i].language;
for(var j= 0; j< data.length; j++) {
if(lang == data[j].language){
array.push(data[j].language);
array.push(data[j].translation);
array.push(data[j].text);
}
}
}
output Required
san:[{"text":"Welcome","question":"san","translation":"willkommen.},
{"text":"ajax","question":"san","translation":"ommen."},
se:[{"text":"Welcome","question":"se","translation":"bienvenida.},
{"text":"ajax","question":"se","translation":"bienve."},
fr:[{"text":"Welcome","question":"fr","translation":"propriétaires.},
{"text":"ajax","question":"fr","translation":"propires."},
I recommend you to use ES6 functions instead of for. You can separate the different processes and make the code more modular and declarative. This way you can change easily the desired output since your code is made by little pieces.
const data = [
{"Id":1,"text":"hi all present ","language":"sde","translation":"Hernjd ndjjsjdj"},
{"Id":1,"text":"hi all present","language":"ses","translation":"dfks kdfk kdfk"},
{"Id":1,"text":"hi all present","language":"sfr","translation":"bsh kkoweofeo"},
{"Id":1,"text":"hi all present","language":"szh","translation":"kdijo keow"},
{"Id":1,"text":"activated","language":"sde","translation":"Konto eid ke"},
{"Id":1,"text":"activated","language":"ses","translation":"La cueweffewfefwef."},
{"Id":1,"text":"activated","language":"sfr","translation":"Cowefrwef"},
{"Id":1,"text":"activated","language":"szh","translation":"fhewjhfwh"},
{"Id":1,"text":"completed","language":"sde","translation":"Ihr fwejiewf"},
{"Id":1,"text":"completed","language":"ses","translation":"Ya hfuwifrw"},
{"Id":1,"text":"completed","language":"sfr","translation":"Votrkwfwe"},
{"Id":1,"text":"completed","language":"szh","translation":"dmksfkwkf"},
{"Id":1,"text":"ACTION","language":"sde","translation":"AKTION"},
{"Id":1,"text":"ACTION","language":"ses","translation":"ACCIONES"},
{"Id":1,"text":"ACTION","language":"fr","translation":"ACTION"}];
// Define the properties that we want to filter for each element
const filterProperties = (item) => ({
text:item.text,
language: item.language,
translation:item.translation
})
// Given a type of languages ('sde'), filter the data in function of this value
const getItemsByLanguage = (language) => {
return data.filter((item) => item.language === language)
}
const onlyUnique = (value, index, self) => {
return self.indexOf(value) === index;
}
// Get the unique values of languages: ['sde', 'ses', 'sfr', ...]
const uniqueLanguages = data.map((item) => item.language).filter(onlyUnique)
// Get all found items for a language ('sde') and get the desired format (returns array of objects)
const resultArray = uniqueLanguages.map((language) => (
{[language]: getItemsByLanguage(language).map(filterProperties)}
))
// Convert the array of objects to single object
const result = Object.assign({}, ...resultArray)
console.log(result)
const data = [
{"Id":1,"text":"hi all present ","language":"sde","translation":"Hernjd ndjjs
jdj"},
{"Id":1,"text":"hi all present","language":"ses","translation":"dfks kdfk
kdfk"},
{"Id":1,"text":"hi all present","language":"sfr","translation":"bsh kkowe
ofeo"},
{"Id":1,"text":"hi all present","language":"szh","translation":"kdijo keow"},
{"Id":1,"text":"activated","language":"sde","translation":"Konto eid ke"},
{"Id":1,"text":"activated","language":"ses","translation":"La cueweffewfef
wef."},
{"Id":1,"text":"activated","language":"sfr","translation":"Cowefrwef"},
{"Id":1,"text":"activated","language":"szh","translation":"fhewjhfwh"},
{"Id":1,"text":"completed","language":"sde","translation":"Ihr fwejiewf"},
{"Id":1,"text":"completed","language":"ses","translation":"Ya hfuwifrw"},
{"Id":1,"text":"completed","language":"sfr","translation":"Votrkwfwe"},
{"Id":1,"text":"completed","language":"szh","translation":"dmksfkwkf"},
{"Id":1,"text":"ACTION","language":"sde","translation":"AKTION"},
{"Id":1,"text":"ACTION","language":"ses","translation":"ACCIONES"},
{"Id":1,"text":"ACTION","language":"fr","translation":"ACTION"}];
// Define the properties that we want to filter for each element
const filterProperties = (data) => ({
text:data.text,
question: data.question,
translation:data.translation
})
// Given a type of question ('san'), filter the data in function of this value
const getQuestions = (question) => {
return data.filter((item) => item.question === question)
}
const onlyUnique = (value, index, self) => {
return self.indexOf(value) === index;
}
// Get the unique values of questions: ['san', 'se', 'fr']
const uniqueQuestions = data.map((item) => item.question).filter(onlyUnique)
// Get all found values for a question and get the desired format (returns
array of objects)
const resultArray = uniqueQuestions.map((question) => (
{[question]: getQuestions(question).map(filterProperties)}
))
// Convert the array of objects to single object
const result = Object.assign({}, ...resultArray)
console.log(result)

Resources