Before
This is an object with multiple rows:
{
"functions": [
{
"package_id": "2",
"module_id": "2",
"data_id": "2"
},
{
"package_id": "1",
"module_id": "1",
"data_id": "2"
},
{
"package_id": "2",
"module_id": "3",
"data_id": "3"
}
]
}
Desired result
I want this to return into a "nested" Object like below, without duplicates:
{
"packages": [
{
"package_id": "2",
"modules": [
{
"module_id": "2",
"data": [
{
"data_id": "2"
}
]
},
{
"module_id": "3",
"data": [
{
"data_id": "3"
}
]
}
]
},{
"package_id": "1",
"modules": [
{
"module_id": "1",
"data": [
{
"data_id": "2"
}
]
}
]
}
]
}
I've already tried loops inside loops, with constructing multiple arrays and objects. Which causes duplicates or overriding objects into single ones. Is there a more generic way to generate this with JavaScript? (It's for an Angular (6) project.
Example 1
getFunctionPackage() {
var fList = this.functionList;
var dArr = [];
var dObj = {};
var pArr = [];
var pObj = {};
var mArr = [];
var mObj = {};
for (var key in fList) {
pObj['package_id'] = fList[key]['package_id'];
mObj['module_id'] = fList[key]['module_id'];
dObj['data_id'] = fList[key]['data_id'];
for (var i = 0; i < pArr.length; i++) {
if (pArr[i].package_id != pObj['package_id']) {
pArr.push(pObj);
}
for (var x = 0; x < mArr.length; x++) {
if (pArr[i]['modules'][x].module_id != mObj['module_id']) {
mArr.push(mObj);
}
for (var y = 0; y < dArr.length; y++) {
if (pArr[i]['modules'][x]['datas'][y].data_id != dObj['data_id']) {
dArr.push(dObj);
}
}
}
}
if (dArr.length == 0) {
dArr.push(dObj);
}
mObj['datas'] = dArr;
if (mArr.length == 0) {
mArr.push(mObj);
}
pObj['modules'] = mArr;
if (pArr.length == 0) {
pArr.push(pObj);
}
dObj = {};
mObj = {};
pObj = {};
}
}
Example 2: Results in skipping cause of the booleans
var fList = this.functionList;
var dArr = [];
var dObj = {};
var pArr = [];
var pObj = {};
var mArr = [];
var mObj = {};
var rObj = {};
for (var key in fList) {
pObj['package_id'] = fList[key]['package_id'];
mObj['module_id'] = fList[key]['module_id'];
dObj['data_id'] = fList[key]['data_id'];
var pfound = false;
var mfound = false;
var dfound = false;
for (var i = 0; i < pArr.length; i++) {
if (pArr[i].package_id == pObj['package_id']) {
for (var x = 0; x < mArr.length; x++) {
if (pArr[i]['modules'][x].module_id == mObj['module_id']) {
for (var y = 0; y < dArr.length; y++) {
if (pArr[i]['modules'][x]['datas'][y].data_id == dObj['data_id']) {
dfound = true;
break;
}
}
mfound = true;
break;
}
}
pfound = true;
break;
}
}
if (!dfound) {
dArr.push(dObj);
mObj['datas'] = dArr;
dObj = {};
}
if (!mfound) {
mArr.push(mObj);
pObj['modules'] = mArr;
mObj = {};
}
if (!pfound) {
pArr.push(pObj);
pObj = {};
}
dArr = [];
mArr = [];
}
rObj['packages'] = pArr;
console.log(rObj);
Here's a more generic approach using Array#reduce()
to create a grouped object based on the package id as keys. You can use any loop to build this same object ... for()
or forEach()
for example.
Then use Object.values()
to get the final array from that grouped object
Using methods like Array#find()
simplifies traversing to see if a module exists already or not within each package
const grouped = data.functions.reduce((a, c )=>{ // if group object doesn't exist - create it or use existing one a[c.package_id] = a[c.package_id] || {package_id : c.package_id, modules: [] } // store reference to the group modules array const mods = a[c.package_id].modules // look within that group modules array to see if module object exists let module = mods.find(mod => mod.module_id === c.module_id) if(!module){ // or create new module object module = {module_id: c.module_id, data:[]} // and push it into modules array mods.push(module); } // push new data object to module data array module.data.push({data_id: c.data_id}) return a }, {}) // create final results object const res = { packages : Object.values(grouped) } console.log(res)
.as-console-wrapper {max-height: 100%!important;}
<script> const data = { "functions": [{ "package_id": "2", "module_id": "2", "data_id": "2" }, { "package_id": "1", "module_id": "1", "data_id": "2" }, { "package_id": "2", "module_id": "3", "data_id": "3" } ] } </script>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.