Reputation: 101
So I have found a solution, but I am still learning and feel like my solution is too long. It does not use all of ES6 and could be better. I would love any feedback and/or suggestions.
The data looks like this:
const formattedWorkbook =
[
{
"year": 2016,
"mainHeaderEnglish": "Pearls of Wisdom",
"categoryCode": 3,
},
{
"year": 2017,
"mainHeaderEnglish": "VENuS Satellite",
"categoryCode": 2,
},
{
"year": 2017,
"mainHeaderEnglish": "Hope for millions",
"categoryCode": 1,
},
{
"year": 2012,
"mainHeaderEnglish": "green electricity Pioneer",
"categoryCode": 2
}
]
The data needs to look like this:
const formattedWorkbook =
[
{
"year": 2016,
"value: [
{"mainHeaderEnglish": "Pearls of Wisdom", "categoryCode": 3,}
]
},
{
"year": 2017,
"value":[
{"mainHeaderEnglish": "VENuS Satellite", "categoryCode": 2},
{"mainHeaderEnglish": "Hope for millions", "categoryCode": 1}
]
},
{
"year": 2012,
"value": [
{"mainHeaderEnglish": "green electricity Pioneer", "categoryCode": 2}
]
}
]
This is my solution that works, but I think it could be a lot better:
let transformedWorkbook = formattedWorkbook.map(function (obj) {
const result = {
year: obj.year,
value: []
}
for (let year in obj) {
if (obj.hasOwnProperty(year) && year !== "year") {
result.value.push({ [year]: obj[year] });
}
}
result.value = [Object.assign({}, ...result.value)]
return result;
});
const newWorkbook = new Map(transformedWorkbook.map(({ year, value }) => [year, { year, value: [] }]));
for (let { year, value } of transformedWorkbook) {
newWorkbook.get(year).value.push(...[value].flat())
};
console.log([...newWorkbook.values()]);
Upvotes: 2
Views: 784
Reputation: 386654
You could still use the map
but take year
out of the object and map new object with the grouped result.
In pieces:
Array.from
takes an iterable, like an Array
or a Map
, where Symbol.iterator
is implemented and a mapping function and returns an array.
To get a grouped dataset, you could take Array#reduce
which uses an accumulator, like an instance of Map
and iterates the given array of objects.
To get a property from the object and keeping the rest,
{ year, ...o }
you could take a destructuring for year
and get the rest if object destructuring. Now you have two parts, the wanted property for grouping and the rest for collecting as value.
Map#get
takes a value from the instance and Map#set
stores the value.
In case of not getting an array as value, you need to use a default value
m.get(year) || []
with logical OR ||
, which returns the first truthy value, like an array, but not undefined
.
This value is spreaded into a new array along with the actual object
[...m.get(year) || [], o]
as new value for the Map
.
Finally the mapping function of Array.from
([year, value]) => ({ year, value })
takes a destructuring of key and value of the given Map
and generates a new object with short hand properties as new result.
const formattedWorkbook = [{ year: 2016, mainHeaderEnglish: "Pearls of Wisdom", categoryCode: 3 }, { year: 2017, mainHeaderEnglish: "VENuS Satellite", categoryCode: 2 }, { year: 2017, mainHeaderEnglish: "Hope for millions", categoryCode: 1 }, { year: 2012, mainHeaderEnglish: "green electricity Pioneer", categoryCode: 2 }],
result = Array.from(
formattedWorkbook.reduce((m, { year, ...o }) =>
m.set(year, [...m.get(year) || [], o]), new Map),
([year, value]) => ({ year, value })
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 4
Reputation: 5872
You can use lodash for that:
_.map(formattedWorkbook, el => {
return {
year: el.year,
value: {
mainHeaderEnglish: el.mainHeaderEnglish,
categoryCode: el.categoryCode
}
}
});
If you prefer native javascript functions:
formattedWorkbook.map(el => {
return {
year: el.year,
value: {
mainHeaderEnglish: el.mainHeaderEnglish,
categoryCode: el.categoryCode
}
}
});
Upvotes: 0
Reputation: 49945
You can use array.reduce to group your array data based on year
:
const formattedWorkbook =
[
{
"year": 2016,
"mainHeaderEnglish": "Pearls of Wisdom",
"categoryCode": 3,
},
{
"year": 2017,
"mainHeaderEnglish": "VENuS Satellite",
"categoryCode": 2,
},
{
"year": 2017,
"mainHeaderEnglish": "Hope for millions",
"categoryCode": 1,
},
{
"year": 2012,
"mainHeaderEnglish": "green electricity Pioneer",
"categoryCode": 2
}
]
let result = formattedWorkbook.reduce((acc,cur) => {
let { year, ...rest } = cur;
let ex = acc.find(x => x.year === year);
if(!ex){
ex = { year, value: [] };
acc.push(ex);
}
ex.value.push(rest);
return acc;
}, [])
console.log(result);
Upvotes: 2