Reputation: 1933
I am receiving data from my API like this:
[
{grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1"},
{grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1"},
{grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1"},
{grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2"},
{grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2"}
]
Thanks to a StackOverflow post, I managed to transform my list to group each item by type like this:
var API_DATA = [
{grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1"},
{grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1"},
{grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1"},
{grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2"},
{grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2"}
];
Array.prototype.groupBy = function(k) {
return this.reduce((acc, item) => ((acc[item[k]] = [...(acc[item[k]] || []), item]), acc),{});
};
TABLE_DATA = API_DATA.groupBy("type")
console.log(TABLE_DATA)
Unfortunately, I cannot use this result in a dataSource of an angular material mat-table
because it is not a list:
Error: Provided data source did not match an array, Observable, or DataSource
How can I retrieve a list consisting of several lists:
[
[
{grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1"},
{grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1"},
{grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1"}
],
[
{grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2"},
{grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2"}
]
]
Thanks for your help.
Upvotes: 3
Views: 92
Reputation: 386560
You could get the values form the object.
Array.prototype.groupBy = function(k) {
return this.reduce((acc, item) => (acc[item[k]] = [...(acc[item[k]] || []), item], acc), {});
};
var API_DATA = [{ grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1" }, { grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1" }, { grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1" }, { grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2" }, { grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2" }],
TABLE_DATA = Object.values(API_DATA.groupBy("type"));
console.log(TABLE_DATA);
.as-console-wrapper { max-height: 100% !important; top: 0; }
UPDATE 2023
With new standard Object.groupBy
:
const
API_DATA = [{ grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1" }, { grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1" }, { grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1" }, { grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2" }, { grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2" }],
TABLE_DATA = Object.values(Object.groupBy(API_DATA, ({ type }) => type));
console.log(TABLE_DATA);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 117
you can use _.groupBy() function on lodash
var jsonArray = [
{grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1"},
{grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1"},
{grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1"},
{grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2"},
{grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2"}
]
var groupJson= _.groupBy(jsonArray, function(jsonArray) {
return jsonArray.type;
});
console.log(groupJson);
<script src='https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js'></script>
Upvotes: 0
Reputation: 2383
You can group this data by two ways.
object
array
Demo
NOTE: I'm using
JSON.stringify(group, null, 2)
. to just prettify the output.
const API_DATA = [
{ grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1" },
{ grade: "Grade B", id: 2, ifsGrade: "B1XX", ifsType: "02XX", points: 15, type: "Type_1" },
{ grade: "Grade C", id: 3, ifsGrade: "C1XX", ifsType: "03XX", points: 1, type: "Type_1" },
{ grade: "Grade A", id: 4, ifsGrade: "A2XX", ifsType: "04XX", points: 23, type: "Type_2" },
{ grade: "Grade B", id: 5, ifsGrade: "B2XX", ifsType: "05XX", points: 26, type: "Type_2" }
];
const groupBy = 'type';
console.log('------------------');
console.log('------Object------');
console.log('------------------');
const group1 = {};
for (let i = 0; i < API_DATA.length; i++) {
const element = API_DATA[i];
const groupByValue = element[groupBy];
if (typeof group1[groupByValue] === 'undefined') {
group1[groupByValue] = [element];
} else {
group1[groupByValue].push(element);
}
}
console.log(JSON.stringify(group1, null, 2))
console.log('-------------------');
console.log('-------Array-------');
console.log('-------------------');
const group2 = [];
const tmp = {};
for (let i = 0; i < API_DATA.length; i++) {
const element = API_DATA[i];
const groupByValue = element[groupBy];
if (typeof tmp[groupByValue] === 'undefined') {
const position = group2.length; // get new position
tmp[groupByValue] = position; // save it
group2[position] = [element];
} else {
const position = tmp[groupByValue];
group2[position].push(element);
}
}
console.log(JSON.stringify(group2, null, 2))
Upvotes: 1
Reputation: 58
Array.prototype.groupBy = function (k) {
return this.reduce(
(acc, item) => ((acc[item[k]] = [...(acc[item[k]] || []), item]), acc),
[]
);
};
Upvotes: 0