嵌套查询结果ES6

时间:2018-08-21 02:23:34

标签: javascript ecmascript-6

我有一个从充满联接的查询返回的JSON结果:

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
    },
]

我需要将此查询结果转换为4级深的嵌套对象数组:

MODEL_NO
    PROCESS_NO
        BOM_ITEM
            ALT_ITEM

如果这些字段具有相同的值,则它们是要嵌套的重要字段。我能找出其余的东西。

要实现这一目标,最容易遵循的模式是什么?我正在学习ES6,以使其尽可能简单?

编辑:我只知道如何嵌套2个级别。请检查下面的代码。

    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
    },{}))

2 个答案:

答案 0 :(得分:1)

按键将数组分成小部分,然后重复递归。这与您在数据库中所做的一样

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>

答案 1 :(得分:0)

reduce函数内部,应该使用另一个 reduce函数创建适当的嵌套对象(如果尚不存在),然后将其返回。最后,您将获得一个数组,可以在其中push放置项目:

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