Grouping Json Based on Multiple Keys Grouping Json Based on Multiple Keys json json

Grouping Json Based on Multiple Keys


Here is my solution of the task (only Javascript):

function getItemByKey(arr, key, value){    // here we look for existing group item in the result array    return arr.reduce(function (prev, cur) {        if (prev == null && cur[key] == value) {            return cur;        }        return prev;    }, null);}function checkPropForGroup(prop, key){    // here we check which columns should stay in the group,    // and which should go down to group items.    return prop == key || prop == key.replace("_id", "_name");}function cloneSuperItem(src, key){    // create super item by copying only group related fields     var item = {};    for (prop in src){        if (checkPropForGroup(prop, key)){            item[prop] = src[prop];        }    }    item[key+'_group'] = [];    return item;}function cloneSubItem(src, key){    // create sub-item by copying all but group related fields     var item = {};    for (prop in src){        if (!checkPropForGroup(prop, key)){            item[prop] = src[prop];        }    }    return item;}function groupArray(arr, args, lvl){    var key = args[lvl];    var result = [];    arr.forEach(function (item, ind, a){        // find or create super item for group and then create sub item         // and push it there         var keyItem = getItemByKey(result, key, item[key]);        if (!keyItem){            keyItem = cloneSuperItem(item, key);            result.push(keyItem);        }        subItem = cloneSubItem(item, key);        keyItem[key+'_group'].push(subItem);    });    if (args[lvl+1]){        // recursively make grouping on lower level         for (var i = 0; i < result.length; i++){            result[i][key+'_group'] =               groupArray(result[i][key+'_group'], args, lvl + 1);        }    }    return result;}function groupArrayMain(arr, keysArray){    // keys should be simply listed as parameters in order from top group to lower    return JSON.stringify(groupArray(arr, arguments, 1),null,'\n')}var arr = [  {    "category_id": "C1",    "category_name": "C1_Name",    "item_id": "C1_I1",    "item_name": "C1_I1_Name",    "variant_id": "C1_I1_V1",    "variant_name": "C1_I1_V1_ Name"  },  {    "category_id": "C1",    "category_name": "C1_Name",    "item_id": "C1_I1",    "item_name": "C1_I1_Name",    "variant_id": "C1_I1_V2",    "variant_name": "C1_I1_V2_ Name"  },  {    "category_id": "C1",    "category_name": "C1_Name",    "item_id": "C1_I2",    "item_name": "C1_I2_Name",    "variant_id": "C1_I2_V1",    "variant_name": "C1_I2_V1_ Name"  },  {    "category_id": "C1",    "category_name": "C1_Name",    "item_id": "C1_I2",    "item_name": "C1_I2_Name",    "variant_id": "C1_I2_V2",    "variant_name": "C1_I2_V2_ Name"  },  {    "category_id": "C2",    "category_name": "C2_Name",    "item_id": "C2_I1",    "item_name": "C2_I1_Name",    "variant_id": "C2_I1_V1",    "variant_name": "C2_I1_V1_ Name"  }]groupArrayMain(arr, "category_id", "item_id", "variant_id")

I also put this as jsfiddle