Как создать вложенный объект из данных, используя JavaScript? - PullRequest
0 голосов
/ 10 февраля 2019

До

Это объект с несколькими строками:

  {
  "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"
    }
  ]
}

Желаемый результат

Я хочу эточтобы вернуться во «вложенный» объект, как показано ниже, без дубликатов:

{
  "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"
            }
          ]
        }
      ]
    }
  ]
}

Я уже пробовал циклы внутри циклов с созданием нескольких массивов и объектов.Что приводит к дублированию или переопределению объектов в отдельные.Есть ли более общий способ генерировать это с помощью JavaScript?(Это для проекта Angular (6).

Пример 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 = {};
        }
    }

Пример 2: Приводит к пропуску логических значений

 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);

1 Ответ

0 голосов
/ 10 февраля 2019

Вот более общий подход, использующий Array#reduce() для создания сгруппированного объекта на основе идентификатора пакета в качестве ключей.Вы можете использовать любой цикл для создания этого же объекта ... for() или forEach(), например.

Затем используйте Object.values(), чтобы получить окончательный массив из этого сгруппированного объекта

Использованиеметоды типа Array#find() упрощают обход, чтобы увидеть, существует ли модуль уже или нет в каждом пакете

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>
...