Reputation: 142
Format the input array , The result should be a grouped array
This is the input Array:
let INPUT_DATA: Object[] = [
{
id: 1,
'a-level': "World",
'b-level': "Asia",
'c-level': "",
'd-level': "",
},
{
id: 2,
'a-level': "World",
'b-level': "Asia",
'c-level': "India",
'd-level': "",
},
{
id: 3,
'a-level': "World",
'b-level': "Asia",
'c-level': "India",
'd-level': "Kerala",
},
{
id: 4,
'a-level': "World",
'b-level': "Europe",
'c-level': "",
'd-level': "",
},
{
id: 5,
'a-level': "World",
'b-level': "Europe",
'c-level': "Italy",
'd-level': "",
},
{
id: 6,
'a-level': "World",
'b-level': "Europe",
'c-level': "Germany",
'd-level': "",
},
{
id: 7,
'a-level': "Day",
'b-level': "",
'c-level': "",
'd-level': "",
}
{
id: 8,
'a-level': "Day",
'b-level': "Hour",
'c-level': "",
'd-level': "",
},
{
id: 9,
'a-level': "Day",
'b-level': "Hour",
'c-level': "Minute",
'd-level': "",
}
];
The output array is a grouped version of the input array.In the input array there are 4 a -level entry that is "world" , But in the output array the world is grouped as one and all the elements inside it is also grouped.
This is the output Array:
let OUTPUT_DATA: Object[] = [
{
id: ",
indexName: 'World',
subIndexLevels: [
{
id: 1,
indexName: 'Asia',
subIndexLevels: [
{
id: 2,
indexName: 'India',
subIndexLevels: [
{
id: 3,
indexName: 'Kerala',
}
]
}
]
},
{
id: 4,
indexName: 'Europe',
subIndexLevels: [
{
id: 5,
indexName: 'Italy',
},
{
id: 6,
indexName: 'Germany',
}
]
}
]
},
{
id: 7,
indexName: 'Day',
subIndexLevels: [
{
id: 8,
indexName: 'Hour',
subIndexLevels: [
{
id: 9,
indexName: 'Minute',
}
]
}
]
},
]
Upvotes: 2
Views: 157
Reputation: 386560
You could take a dynamic approach and filter the names for the levels and seach for it in every level.
If not found, create a new object for the level.
At the end assign id
to the latest object.
var data = [{ id: 1, "a-level": "World", "b-level": "Asia" }, { id: 2, "a-level": "World", "b-level": "Asia" }, { id: 2, "a-level": "World", "b-level": "Asia", "c-level": "India" }, { id: 3, "a-level": "World", "b-level": "Asia", "c-level": "India", "d-level": "Kerala" }, { id: 4, "a-level": "World", "b-level": "Europe" }, { id: 5, "a-level": "World", "b-level": "Europe", "c-level": "Italy" }, { id: 6, "a-level": "World", "b-level": "Europe", "c-level": "Germany" }, { id: 7, "a-level": "Day" }, { id: 8, "a-level": "Day", "b-level": "Hour" }, { id: 9, "a-level": "Day", "b-level": "Hour", "c-level": "Minute"}],
keys = ["a-level", "b-level", "c-level", "d-level"],
result = data.reduce((r, o) => {
var target = keys.map(k => o[k])
.filter(Boolean)
.reduce((level, indexName) => {
var temp = (level.subIndexLevels = level.subIndexLevels || [])
.find(q => q.indexName === indexName);
if (!temp) level.subIndexLevels.push(temp = { id: '', indexName });
return temp;
}, { subIndexLevels: r });
target.id = target.id
? target.id + ',' + o.id
: o.id;
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 22213
Try like this:
constructor() {
var aLevelDistinctData = this.GetDistinctValues(this.INPUT_DATA, "a-level");
aLevelDistinctData.forEach(a_item => {
var asubIndexLevels = [];
var a_itemSubLevels = this.INPUT_DATA.filter(x => x["a-level"] == a_item["a-level"]);
var bLevelDistinctData = this.GetDistinctValues(a_itemSubLevels, "b-level");
bLevelDistinctData = bLevelDistinctData.filter(x => x["b-level"] != "");
bLevelDistinctData.forEach(b_item => {
var bsubIndexLevels = [];
var b_itemSubLevels = a_itemSubLevels.filter(x => x["b-level"] == b_item["b-level"] && b_item["a-level"] == a_item["a-level"]);
var csubIndexLevels = [];
var cLevelDistinctData = this.GetDistinctValues(b_itemSubLevels, "c-level");
cLevelDistinctData = cLevelDistinctData.filter(x => x["c-level"] != "");
cLevelDistinctData.forEach(c_item => {
var c_itemSubLevels = b_itemSubLevels.filter(x => x["c-level"] == c_item["c-level"] && c_item["b-level"] == b_item["b-level"]);
var dLevelDistinctData = this.GetDistinctValues(c_itemSubLevels, "d-level");
dLevelDistinctData = dLevelDistinctData.filter(x => x["d-level"] != "");
dLevelDistinctData.forEach(d_item => {
csubIndexLevels.push({
id: d_item["id"],
indexName: d_item["d-level"]
});
});
bsubIndexLevels.push({
id: c_item["id"],
indexName: c_item["c-level"],
subIndexLevels: [...csubIndexLevels]
});
});
asubIndexLevels.push({
id: b_item["id"],
indexName: b_item["b-level"],
subIndexLevels: [...bsubIndexLevels]
});
});
this.OUTPUT_DATA.push({
id: a_item["id"],
indexName: a_item["a-level"],
subIndexLevels: [...asubIndexLevels]
});
});
console.log(this.OUTPUT_DATA);
}
GetDistinctValues(Source: Array<any>, FilterKey: string = null): Array<any> {
let DistinctArray = [];
try {
Source.forEach(e => {
if (FilterKey !== null && FilterKey !== undefined && FilterKey !== "") {
if (
DistinctArray.filter(DE => DE[FilterKey] === e[FilterKey]).length <=
0
)
DistinctArray.push(e);
} else {
if (DistinctArray.indexOf(e) === -1) DistinctArray.push(e);
}
});
} catch (error) {
DistinctArray = [];
}
return DistinctArray;
}
Note: You can take this idea and refactor it further.
Upvotes: 2
Reputation: 2027
Checkout this Library , This provides good options for grouping nested elements. https://github.com/danrevah/ngx-pipes#groupby
Upvotes: 0