Reputation: 150
So, I am trying to create a list of list of objects using some existing data. The data i have contains 2 values i.e. 'a' and 'b' with many similar values of 'a' recurring many times in the dataset.
What i am trying to do is to convert the data in such a format that for any value of 'a', the list would contain all the value of 'b' corresponding to its 'a' value in a single place.
The Dataset is :
const tempData = [
{a: 1557637200025, b: "aaaa"},
{a: 1557637200025, b: "bbbb"},
{a: 1557637200025, b: "cccc"},
{a: 1557637200025, b: "dddd"},
{a: 1557637200025, b: "eeee"},
{a: 1557637200025, b: "ffff"},
{a: 1557637200025, b: "gggg"},
{a: 1555563600017, b: "hhhh"},
{a: 1555563600017, b: "iiii"},
{a: 1555563600017, b: "jjjj"},
{a: 1555563600017, b: "kkkk"},
{a: 1555563600017, b: "llll"},
{a: 1555563600017, b: "mmmm"},
{a: 1555563600017, b: "nnnn"},
{a: 1555563600017, b: "oooo"},
{a: 1555563600017, b: "pppp"},
{a: 1555563600017, b: "qqqq"},
{a: 1555563600017, b: "rrrr"},
{a: 1555563600017, b: "ssss"},
{a: 1555563600017, b: "tttt"},
{a: 1555563600017, b: "uuuu"},
{a: 1557982800028, b: "vvvv"},
]
And i want it to look like this:
const newTempData = [
{
a: 1557637200025,b: [
"aaaa",
"bbbb",
...
]},
{
a: 1555563600017,b: [
"hhhh",
"iiii",
]},
...
]
I have tried basic nested for
loops and i am getting no where close to achieve what i am seeking.I am not getting any way to update the row1 value inside for loop for row2, so that i can stop the loop to match the values again and again.
var newTempData =[];
for(let row1 in tempData){
console.log(row1);
var some =[];
var row2 = Number(row1)+1;
var x = tempData[row1].a;
for(row2 in tempData) {
var y = tempData[row2].a;
var instance = tempData[row2].b;
if( x === y ){
some.push({ ins : instance});
}
}
newTempData.push({a: x,b: some});
}
console.log(newTempData);
The output i am getting is this.
0: {a: 1557637200025, b: Array(7)}
1: {a: 1557637200025, b: Array(7)}
2: {a: 1557637200025, b: Array(7)}
3: {a: 1557637200025, b: Array(7)}
4: {a: 1557637200025, b: Array(7)}
5: {a: 1557637200025, b: Array(7)}
6: {a: 1557637200025, b: Array(7)}
7: {a: 1555563600017, b: Array(14)}
8: {a: 1555563600017, b: Array(14)}
9: {a: 1555563600017, b: Array(14)}
10: {a: 1555563600017, b: Array(14)}
11: {a: 1555563600017, b: Array(14)}
12: {a: 1555563600017, b: Array(14)}
13: {a: 1555563600017, b: Array(14)}
14: {a: 1555563600017, b: Array(14)}
15: {a: 1555563600017, b: Array(14)}
16: {a: 1555563600017, b: Array(14)}
17: {a: 1555563600017, b: Array(14)}
18: {a: 1555563600017, b: Array(14)}
19: {a: 1555563600017, b: Array(14)}
20: {a: 1555563600017, b: Array(14)}
21: {a: 1557982800028, b: Array(1)}
I just want to get the desired data without repetition. Right now i am able to get the data but it is repeating for every matched value of 'a'. I want to know better ways to do it rather than my amateur way. Thanks.
Upvotes: 2
Views: 100
Reputation: 2932
If you care about performance, instead of using .find()
of your array, you could use a Map
:
function add(map, {a,b}) {
if (!map.has(a)) {
map.set(a, {a:a, b:[]});
}
map.get(a).b.push(b);
return map;
}
const result = Array.from(tempData.reduce(add, new Map()).values());
EDIT: or even better, use an object as in @Vishal Sharma's answer, has less overhead than a map.
Upvotes: 2
Reputation: 2610
Instead of running .find
each time you could create an object {}
as part of reduce, to avoid the effort of finding the element each time, and later use Object.values
const result = Object.values(tempData.reduce((acc, {a, b}) => {
if (acc[a]) {
acc[a].b.push(b)
} else {
acc[a] = {a, b: [b]}
}
return acc
}, {}))
Upvotes: 1
Reputation: 9682
Try with reduce. I have commented out the check if b
is already in the array, depends if you want repeated b
values or not.
const tempData = [
{ a: 1557637200025, b: "aaaa" },
{ a: 1557637200025, b: "bbbb" },
{ a: 1557637200025, b: "cccc" },
{ a: 1557637200025, b: "dddd" },
{ a: 1557637200025, b: "eeee" },
{ a: 1557637200025, b: "ffff" },
{ a: 1557637200025, b: "gggg" },
{ a: 1555563600017, b: "hhhh" },
{ a: 1555563600017, b: "iiii" },
{ a: 1555563600017, b: "jjjj" },
{ a: 1555563600017, b: "kkkk" },
{ a: 1555563600017, b: "llll" },
{ a: 1555563600017, b: "mmmm" },
{ a: 1555563600017, b: "nnnn" },
{ a: 1555563600017, b: "oooo" },
{ a: 1555563600017, b: "pppp" },
{ a: 1555563600017, b: "qqqq" },
{ a: 1555563600017, b: "rrrr" },
{ a: 1555563600017, b: "ssss" },
{ a: 1555563600017, b: "tttt" },
{ a: 1555563600017, b: "uuuu" },
{ a: 1557982800028, b: "vvvv" }
];
const result = tempData.reduce((acc, { a, b }) => {
const element = acc.find(el => el.a === a);
// If element exists
if (element /* && !element.b.includes(b) */) {
element.b.push(b);
return acc;
}/* else if ( element ) { return acc; } */
acc.push({ a, b: [b] });
return acc;
}, []);
Upvotes: 4