I would like to chart my data. However, the data I get from server needs to be completely transformed, and I would like to transform it as quick as possible. I believed reduce would be the best way to go about this in linear time. However, I am not sure if I am fully exploiting it.
- The data from server needs to be reorganized into three categories: country, occupation, and age
- When I encounter a country, occupation, or age, I need to group them under their appropriate category and increment their count.
In my code, I am using reduce to loop over the items once. I am hashing to find duplicates. I am using some also hashing to locate the category titles in the nested arrays in order to increment the count.
This is the original data:
var object = {
dataset: [
{
name: "Sarah",
age: "23",
gender: "female",
country: "australia",
occupation: "student"
},
{
name: "Randy",
age: "19",
gender: "male",
country: "america",
occupation: "student"
},
{
name: "Roger",
age: "32",
gender: "male",
country: "germany",
occupation: "software professional"
},
{
name: "Maverick",
age: "10",
gender: "male",
country: "america",
occupation: "student"
},
{
name: "Riya",
age: "25",
gender: "female",
country: "australia",
occupation: "software professional"
},
{
name: "Glade",
age: "30",
gender: "female",
country: "India",
occupation: "teacher"
}
]
};
This is the desired transformation:
[
{
"name": "country",
"dataset": [
{
"value": "australia",
"count": 2,
"color": "#878BB6"
},
{
"value": "america",
"count": 2,
"color": "#878BB6"
},
{
"value": "germany",
"count": 1,
"color": "#878BB6"
},
{
"value": "India",
"count": 1,
"color": "#878BB6"
}
]
}
] [
{
"name": "occupation",
"dataset": [
{
"value": "student",
"count": 3,
"color": "#878BB6"
},
{
"value": "software professional",
"count": 2,
"color": "#878BB6"
},
{
"value": "teacher",
"count": 1,
"color": "#878BB6"
}
]
}
] [
{
"name": "age",
"dataset": [
{
"value": "23",
"count": 1,
"color": "#878BB6"
},
{
"value": "19",
"count": 1,
"color": "#878BB6"
},
{
"value": "32",
"count": 1,
"color": "#878BB6"
},
{
"value": "10",
"count": 1,
"color": "#878BB6"
},
{
"value": "25",
"count": 1,
"color": "#878BB6"
},
{
"value": "30",
"count": 1,
"color": "#878BB6"
}
]
}
]
This is my working code:
const object = {
dataset: [{
name: "Sarah",
age: "23",
gender: "female",
country: "australia",
occupation: "student"
},
{
name: "Randy",
age: "19",
gender: "male",
country: "america",
occupation: "student"
},
{
name: "Roger",
age: "32",
gender: "male",
country: "germany",
occupation: "software professional"
},
{
name: "Maverick",
age: "10",
gender: "male",
country: "america",
occupation: "student"
},
{
name: "Riya",
age: "25",
gender: "female",
country: "australia",
occupation: "software professional"
},
{
name: "Glade",
age: "30",
gender: "female",
country: "India",
occupation: "teacher"
}
]
};
var mapping = Object.values(object.dataset).reduce(
(function(graph) {
graph = {
hash: {},
index: {}
};
let {
hash,
index
} = graph;
hash = {
"graph-data": [
[{
name: "country",
dataset: []
}],
[{
name: "occupation",
dataset: []
}],
[{
name: "age",
dataset: []
}]
]
};
return function(acc, item) {
hash[item.country] && hash["graph-data"][0][0].dataset[index[item.country]].count++;
if (!hash[item.country]) {
hash[item.country] = true;
hash["graph-data"][0][0].dataset.push({
value: item.country,
count: 1,
color: "#878BB6"
});
index[item.country] = hash["graph-data"][0][0].dataset.length - 1;
}
hash[item.occupation] && hash["graph-data"][1][0].dataset[index[item.occupation]].count++;
if (!hash[item.occupation]) {
hash[item.occupation] = true;
hash["graph-data"][1][0].dataset.push({
value: item.occupation,
count: 1,
color: "#878BB6"
});
index[item.occupation] = hash["graph-data"][1][0].dataset.length - 1;
}
hash[item.age] && hash["graph-data"][2][0].dataset[index[item.age]].count++;
if (!hash[item.age]) {
hash[item.age] = true;
hash["graph-data"][2][0].dataset.push({
value: item.age,
count: 1,
color: "#878BB6"
});
index[item.age] = hash["graph-data"][2][0].dataset.length - 1;
}
acc = hash;
return acc;
};
})(Object.create(null)), {}
);
console.log(...mapping["graph-data"]);
groupBy
for the grouping transforms (quick, incomplete example code. 2. Don't couple your graph coloring logic to the grouping logic. Do it in a separate pass. You'll still have linear performance. \$\endgroup\$reduce
,map
,some
, etc are just library functions that have been standardized into the language. \$\endgroup\$