简体   繁体   中英

Nesting Query Result ES6

I have a JSON result returned from a query full of joins:

 var q = [ { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 5, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item A", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": null, "ALT_TYPE": null }, { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 5, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item B", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": "Alt A", "ALT_TYPE": "A" }, { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 5, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item B", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": "Alt B", "ALT_TYPE": "A" }, { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 6, "PROCESS_ORDER": 2, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item C", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": null, "ALT_TYPE": null }, { "MODEL_ID": 2, "MODEL_NO": "Model B", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 11, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": null, "BOM_QTY": null, "BOM_YIELD": null, "ALT_ITEM": null, "ALT_TYPE": null }, ]

I needed to convert this query result into an array of nested objects 4 levels deep:

MODEL_NO
    PROCESS_NO
        BOM_ITEM
            ALT_ITEM

These are the important fields to nest if they have the same value. I can figure out the rest.

What's the easiest pattern to follow to achieve this? I'm learning ES6 to make this as simple as possible?

EDIT: I only know how to nest 2 levels deep. Please check code below.

    result = Object.values(response.data.reduce((r,{MODEL_ID, MODEL_NO, PROCESS_REV, BOM_REV, PROCESS_NO, PROCESS_ORDER, PROCESS_YIELD, BOM_ITEM, BOM_QTY, BOM_YIELD, ALT_ITEM, ALT_TYPE}) => {
      r[MODEL_ID] = r[MODEL_ID] || { MODEL_NO, PROCESS_REV, BOM_REV, PROCESS : [] }
      r[MODEL_ID].PROCESS.push({ PROCESS_NO, PROCESS_ORDER, PROCESS_YIELD })
      return r
    },{}))

Group array by key to small parts, then repeat recursive. This is same as what you do in database

 var q = [ { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 5, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item A", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": null, "ALT_TYPE": null }, { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 5, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item B", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": "Alt A", "ALT_TYPE": "A" }, { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 5, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item B", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": "Alt B", "ALT_TYPE": "A" }, { "MODEL_ID": 1, "MODEL_NO": "Model A", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 6, "PROCESS_ORDER": 2, "PROCESS_YIELD": 100.000000, "BOM_ITEM": "Item C", "BOM_QTY": 1.000000, "BOM_YIELD": 99.000000, "ALT_ITEM": null, "ALT_TYPE": null }, { "MODEL_ID": 2, "MODEL_NO": "Model B", "PROCESS_REV": 0, "BOM_REV": 1, "PROCESS_NO": 11, "PROCESS_ORDER": 1, "PROCESS_YIELD": 100.000000, "BOM_ITEM": null, "BOM_QTY": null, "BOM_YIELD": null, "ALT_ITEM": null, "ALT_TYPE": null }, ]; function groupBy(arr, predicate) { const uniqueKeys = arr.reduce((acc, o) => { const val = predicate(o); return acc.indexOf(val) === -1 ? [...acc, val] : acc; }, []); return uniqueKeys.map((s) => arr.filter((o) => predicate(o) === s)); }; const modelNos = groupBy(q, (m) => m.MODEL_NO) .map((models) => ({ MODEL_NO: models[0].MODEL_NO, PROCESS_NOS: groupBy(models, (o) => o.PROCESS_NO) .map((processes) => ({ PROCESS_NO: processes[0].PROCESS_NO, BOM_ITEMS: groupBy(processes, (o) => o.BOM_ITEM) .map((boms) => ({ BOM_ITEM: boms[0].BOM_ITEM, ALT_ITEMS: groupBy(boms, (o) => o.ALT_ITEM) .map((m) => m.ALT_ITEM) })) })) })); const el = document.getElementById('result'); el.innerHTML = JSON.stringify(modelNos, null, 2);
 <p id="result"></p>

Inside the reduce function, you should use another reduce function to create the appropriate nested object, if it doesn't exist yet, and return it. At the end, you'll be left with an array, to which you can push the item:

 const arr=[{"MODEL_ID":1,"MODEL_NO":"Model A","PROCESS_REV":0,"BOM_REV":1,"PROCESS_NO":5,"PROCESS_ORDER":1,"PROCESS_YIELD":100.000000,"BOM_ITEM":"Item A","BOM_QTY":1.000000,"BOM_YIELD":99.000000,"ALT_ITEM":null,"ALT_TYPE":null},{"MODEL_ID":1,"MODEL_NO":"Model A","PROCESS_REV":0,"BOM_REV":1,"PROCESS_NO":5,"PROCESS_ORDER":1,"PROCESS_YIELD":100.000000,"BOM_ITEM":"Item B","BOM_QTY":1.000000,"BOM_YIELD":99.000000,"ALT_ITEM":"Alt A","ALT_TYPE":"A"},{"MODEL_ID":1,"MODEL_NO":"Model A","PROCESS_REV":0,"BOM_REV":1,"PROCESS_NO":5,"PROCESS_ORDER":1,"PROCESS_YIELD":100.000000,"BOM_ITEM":"Item B","BOM_QTY":1.000000,"BOM_YIELD":99.000000,"ALT_ITEM":"Alt B","ALT_TYPE":"A"},{"MODEL_ID":1,"MODEL_NO":"Model A","PROCESS_REV":0,"BOM_REV":1,"PROCESS_NO":6,"PROCESS_ORDER":2,"PROCESS_YIELD":100.000000,"BOM_ITEM":"Item C","BOM_QTY":1.000000,"BOM_YIELD":99.000000,"ALT_ITEM":null,"ALT_TYPE":null},{"MODEL_ID":2,"MODEL_NO":"Model B","PROCESS_REV":0,"BOM_REV":1,"PROCESS_NO":11,"PROCESS_ORDER":1,"PROCESS_YIELD":100.000000,"BOM_ITEM":null,"BOM_QTY":null,"BOM_YIELD":null,"ALT_ITEM":null,"ALT_TYPE":null},] const keys = ['MODEL_ID', 'PROCESS_NO', 'BOM_ITEM', 'ALT_ITEM']; const res = arr.reduce((outer, item) => { keys.reduce((a, propName, i) => { const key = item[propName]; if (!a[key]) a[key] = i === 3 ? [] : {}; return a[key]; }, outer) .push(item); return outer; },{}); // First item in your original array: console.log(res ['1'] // model_no ['5'] // process_no ['Item A'] // bom_item ['null'] // alt_item );

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM