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 .
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)
}
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.
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
}
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)