I have a JavaScript object, lets say parentObj
.
How can I improve the below code. I have a reduce
, a map
and a double for loop
.
[
{
NAME: 'SOMENAME',
ID: '1',
FROM: '20191223',
TO: '99991231'
},
{
NAME: 'SOMENAME',
ID: '2',
FROM: '20191223',
TO: '99991231'
},
{
NAME: 'SOMENAME',
ID: '3',
FROM: '20191223',
TO: '99991231'
}
]
I created a new object.
const newObj = .reduce(
function (obj, item) {
obj[item.NAME] = obj[item.NAME] || [];
obj[item.NAME].push(item.ID);
return obj;
},
{}
);
Then a new array of object out of it.
const newObjArr = Object.keys(newObj ).map(function (key) {
return { NAME: key, ID: newObj [key] };
});
And then a double for loop.
for (let item1 of newObjArr) {
for (let item2 of parentObj) {
if (item1.NAME=== item2.NAME) {
finalObjArr.push({ NAME: item1.NAME, ID: item1.ID, FROM: item2.FROM, TO: item2.TO});
}
}
}
My final output:
[
{
NAME: 'SOMENAME',
ID: [1, 2, 3],
FROM: '20191223',
TO: '99991231'
},
...
]
You could use the following:
// sample data
let parentObj = [{NAME: 'SOMENAME',ID: '1',FROM: '20171223',TO: '99991231'},{NAME: 'SOMENAME',ID: '2',FROM: '20181223',TO: '99991231'},{NAME: 'SOMENAME',ID: '3',FROM: '20191223',TO: '99991231'}];
let map = new Map(parentObj.map(o => [o.NAME, []]));
parentObj.forEach(o => map.get(o.NAME).push(o));
let finalObjArr = Array.from(map.values(), arr =>
arr.map(o => ({...o, ID: arr.map(o => o.ID)}))
).flat();
console.log(finalObjArr);
The difference with your own solution is that each ID
array in the output will now be independent. So if you would mutate one, that change would not show up in another object.
I used array.flat()
which is not in ES6 (you mentioned ES6). If that is an issue, then use [].concat(...array)
instead.
You already have that newObj
where you can look up things by name. No need to build that newObjArr
and loop over it to search by name. Just write
for (const item2 of parentObj) {
const item1_NAME = item2.NAME;
const item1_IDs = newObj[item1_NAME];
finalObjArr.push({ NAME: item1_NAME, ID: item1_IDs, FROM: item2.FROM, TO: item2.TO});
}
Given your updates in the comments, I'd suggest you actually put your objects with all info in the newObj
, then all you need to get are its values as an array:
const newObj = parentObj.reduce((obj, item) => {
if (!(item.NAME in obj))
obj[item.NAME] = { NAME: item.NAME, ID: [], FROM: item.FROM, TO: item.TO };
obj[item.NAME].ID.push(item.ID);
return obj;
}, {});
const finalObjArr = Object.values(newObj);
This might be what you want.
const parentObj = [{
NAME: 'SOMENAME',
ID: '1',
FROM: '20191223',
TO: '99991231'
},
{
NAME: 'SOMENAME',
ID: '2',
FROM: '20191223',
TO: '99991231'
},
{
NAME: 'SOMENAME',
ID: '3',
FROM: '20191223',
TO: '99991231'
}]
const ids = parentObj.reduce((p,{NAME, ID})=>
((p[NAME] || (p[NAME] = [])),
(p[NAME].push(ID)), p), {})
console.log(parentObj.map(({NAME, FROM, TO})=>
({NAME, ID: ids[NAME], FROM, TO})))
Or this might be what you want. There was a possibility of ambiguity based on your comment on another answer:
const parentObj = [{
NAME: 'SOMENAME',
ID: '1',
FROM: '20191223',
TO: '99991231'
},
{
NAME: 'SOMENAME',
ID: '2',
FROM: '20191223',
TO: '99991231'
},
{
NAME: 'SOMENAME',
ID: '3',
FROM: '20191223',
TO: '99991231'
}]
console.log(Object.values(parentObj.reduce(
(p,{NAME, ID, FROM, TO})=>
((p[NAME] || (p[NAME] = {NAME, ID: [], FROM, TO})),
(p[NAME]['ID'].push(ID)), p), {})))
how to make req.query only accepts date format like yyyy-mm-dd
Start Application class A from different Application class B in same Android bundle
How can I get data for select box and set the data while using searching?
Is it possible to log the bytes which a server sends? [closed]
I want to display some items with a flatlist, when I tap on the item I want it to turn greenThe issue I having is that I tap on a couple of the item and then I search for a device, for example: 112
For webHey is there any possible to download url of files from firestore storage without providing the file name in the storage reference ? Like if we have to download and display all the images from a particular folder, is it must to know the names of all the files uploaded...
I set up a webpack configuration, that uses the MiniCssExtractPlugin to compile my css into a single file into my public folder