2015-03-05 18 views
5

mi hanno una struttura JSON come qui di seguitoRaggruppamento JSON In base a chiavi multiple

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

Vorrei gruppo livello JSON per N' in javascript, dire che passando l'elenco dei tasti. Per esempio dando category_id, item_id e variant_id, mi aspetto la seguente risposta:

[ 
    { 
    "category_id": "C1", 
    "category_name": "C1_Name", 
    "item": [ 
     { 
     "item_id": "C1_I1", 
     "item_name": "C1_I1_Name", 
     "variant": [ 
      { 
      "variant_id": "C1_I1_V1", 
      "variant_name": "C1_I1_V1_ Name" 
      }, 
      { 
      "variant_id": "C1_I1_V2", 
      "variant_name": "C1_I1_V2_ Name" 
      } 
     ] 
     }, 
     { 
     "item_id": "C1_I2", 
     "item_name": "C1_I2_Name", 
     "variant": [ 
      { 
      "variant_id": "C1_I2_V1", 
      "variant_name": "C1_I2_V1_ Name" 
      }, 
      { 
      "variant_id": "C1_I2_V2", 
      "variant_name": "C1_I2_V2_ Name" 
      } 
     ] 
     } 
    ] 
    } 
] 

avrebbe bisogno di un aiuto su come andare su questo?

Ho provato qualcosa di simile al seguente, ma si raggruppa per un livello. Mi piacerebbe che fosse ricorsivo.

function groupBy(collection, property) { 
    var i = 0, val, index, values = [], result = []; 
    for (; i < collection.length; i++) { 
     val = collection[i][property]; 
     index = values.indexOf(val); 
     if (index > -1) 
      result[index].push(collection[i]); 
     else { 
      values.push(val); result.push([collection[i]]); 
     } 
    } 
    return result; 
} 
+0

ho provato qualcosa di simile a quanto segue, ma gruppi per un livello, i vorrebbe che fosse ricorsivo [codice] functionBy (raccolta, proprietà) { var i = 0, val, index, values ​​= [], result = []; per (; i -1) risultato [indice] .push (raccolta [i]); else { values.push (val); result.push ([collezione [i]]); } } risultato di ritorno; } – Madhan

+0

si desidera passare un elenco di nomi chiave o valori? – user937284

+0

nomi di chiavi (nell'esempio precedente, ho bisogno di passare category_id, item_id, variant_id come elenco – Madhan

risposta

0

Ecco la mia soluzione del compito (solo 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") 

Ho messo questo come jsfiddle

Problemi correlati