结合项目推送内部阵列减少

时间:2018-03-20 08:15:09

标签: javascript ecmascript-6

我有这段代码:

let result = Object.values(response.data.reduce((r,{ PO_NO, PO_LINE_NO, MATERIAL_NO, MATERIAL_NAME, PO_QTY, GRPO_QTY, GRPO_SHIPDATE }) => {
    r[PO_NO] = r[PO_NO] || { PO_NO, LINES: [] }
    r[PO_NO].LINES.push({ 
        LINE_NO: PO_LINE_NO, 
        PO_QTY: PO_QTY, 
        MATERIAL_NO: MATERIAL_NO, 
        MATERIAL_NAME: MATERIAL_NAME, 
        GRPO_QTY: GRPO_QTY, 
        GRPO_SHIPDATE: GRPO_SHIPDATE 
    })
    return r
},{}))

这导致嵌套对象数组。但是,在 LINES.push()部分中,有些项具有相同的line_no,material_no,material_name和po_qty。区别在于grpo_qty和grpo_shipdate。

是否可以删除shipdate并为每个po_no获取与相同line_no的grpo_qty之和,以便每个po_no的每行line_no只有一行?

response.data内容示例:

  {
    "PO_NO": 35159,
    "LINES": [
      {
        "LINE_NO": 15,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 160000,
        "GRPO_SHIPDATE": "September, 21 2017 00:00:00"
      },
      {
        "LINE_NO": 15,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 320800,
        "GRPO_SHIPDATE": "October, 07 2017 00:00:00"
      },
      {
        "LINE_NO": 15,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 19200,
        "GRPO_SHIPDATE": "October, 20 2017 00:00:00"
      },
      {
        "LINE_NO": 16,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 60000,
        "GRPO_SHIPDATE": "September, 13 2017 00:00:00"
      },
      {
        "LINE_NO": 16,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 440000,
        "GRPO_SHIPDATE": "October, 20 2017 00:00:00"
      }
    ]
  },

3 个答案:

答案 0 :(得分:1)

编写函数matchLinecombineLine帮助我们将groupPoLines分解为更简单的任务 - 请注意,此处的每个函数都不会改变其输入

const matchLine = (a, b) =>
  a.LINE_NO === b.LINE_NO
    && a.PO_QTY === b.PO_QTY
    && a.MATERIAL_NO === b.MATERIAL_NO

const combineLine = ({ GRPO_SHIPDATE:_, ...a }, b) =>
  ({ ...a, GRPO_QTY: a.GRPO_QTY + b.GRPO_QTY })

const groupPoLines = ({ LINES, ...po }) => ({
  ...po,
  LINES: LINES.reduce ((r, x) => {
      const i = r.findIndex (y => matchLine (x, y))
      if (i < 0)
        return [ ...r, x ]
      else
        return Object.assign (r, { [i]: combineLine (r[i], x) })
    }, [])
})

console.log (groupPoLines (data))
// { PO_NO: 35159,
//   LINES: 
//   [ { LINE_NO: 15,
//       PO_QTY: 500000,
//       MATERIAL_NO: '130227',
//       MATERIAL_NAME: 'T3-0381 Base Mold  φ10 M2',
//       GRPO_QTY: 500000 },
//     { LINE_NO: 16,
//       PO_QTY: 500000,
//       MATERIAL_NO: '130227',
//       MATERIAL_NAME: 'T3-0381 Base Mold  φ10 M2',
//       GRPO_QTY: 500000 } ] }

如果你有一组PO,你可以简单地map我们的新功能

console.log (poList.map (po => groupPoLines (po)))
// [ { PO_NO: 1, LINES: [ ... ] }, { PO_NO: 2, LINES: [ ... ] } ] 

展开代码段以验证其是否有效

const data = {
  "PO_NO": 35159,
  "LINES": [
    {
      "LINE_NO": 15,
      "PO_QTY": 500000,
      "MATERIAL_NO": "130227",
      "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
      "GRPO_QTY": 160000,
      "GRPO_SHIPDATE": "September, 21 2017 00:00:00"
    },
    {
      "LINE_NO": 15,
      "PO_QTY": 500000,
      "MATERIAL_NO": "130227",
      "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
      "GRPO_QTY": 320800,
      "GRPO_SHIPDATE": "October, 07 2017 00:00:00"
    },
    {
      "LINE_NO": 15,
      "PO_QTY": 500000,
      "MATERIAL_NO": "130227",
      "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
      "GRPO_QTY": 19200,
      "GRPO_SHIPDATE": "October, 20 2017 00:00:00"
    },
    {
      "LINE_NO": 16,
      "PO_QTY": 500000,
      "MATERIAL_NO": "130227",
      "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
      "GRPO_QTY": 60000,
      "GRPO_SHIPDATE": "September, 13 2017 00:00:00"
    },
    {
      "LINE_NO": 16,
      "PO_QTY": 500000,
      "MATERIAL_NO": "130227",
      "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
      "GRPO_QTY": 440000,
      "GRPO_SHIPDATE": "October, 20 2017 00:00:00"
    }
  ]
}

const matchLine = (a, b) =>
  a.LINE_NO === b.LINE_NO
    && a.PO_QTY === b.PO_QTY
    && a.MATERIAL_NO === b.MATERIAL_NO
    
const combineLine = ({ GRPO_SHIPDATE:_, ...a }, b) =>
  ({ ...a, GRPO_QTY: a.GRPO_QTY + b.GRPO_QTY })

const groupPoLines = ({ LINES, ...po }) => ({
  ...po,
  LINES: LINES.reduce ((r, x) => {
      const i = r.findIndex (y => matchLine (x, y))
      if (i < 0)
        return [ ...r, x ]
      else
        return Object.assign (r, { [i]: combineLine (r[i], x)})
    }, [])
})

console.log (groupPoLines (data))

console.log ('---')

console.log ([data, data, data].map(d => groupPoLines (d)))

答案 1 :(得分:0)

我认为你可以迭代每个条目并在lines数组上调用reduce函数。在此函数中,您可以创建一个唯一的键,其属性保持不变,然后总结grpo_qty值。

它可能看起来像这样

result.forEach(entry => {
    entry.LINES = Object.values(entry.LINES.reduce((result, current) => {
        const uniqueKey = `${current.LINE_NO}-${current.MATERIAL_NO}-${current.PO_QTY}-${current.MATERIAL_NAME}`;
        if (!result[uniqueKey]) {
            result[uniqueKey] = {
                LINE_NO: current.LINE_NO,
                PO_QTY: current.PO_QTY,
                MATERIAL_NO: current.MATERIAL_NO,
                MATERIAL_NAME: current.MATERIAL_NAME,
                GRPO_QTY: 0,
            };
        }
        result[uniqueKey].GRPO_QTY += current.GRPO_QTY;

        return result;
    }, {}));
});

也许你可以提供一个jsfiddle,这样更容易测试。

您还可以想象在原始缩小中执行此操作。在那里创建唯一键并总结值。然后你只需要将对象转换回数组。

理论上,也可以直接在数组中写入所有内容并使用array.find()查找现有条目,但我个人建议使用其中一个reduce。它更清洁,更高效,更易于阅读

答案 2 :(得分:0)

我会迭代数组并总结数量:

const newLines = [],
    lineNumbers = [];
lines.forEach(line => {
    delete line.GRPO_SHIPDATE; /* delete shipdate */
    if (!lineNumbers.includes(line.LINE_NO)) {
        lineNumbers.push(line.LINE_NO); /* store current LINE_NO */
        newLines.push(line);
    } else {
        let toChange = newLines.filter(ln => { /* get current LINE_NO */
            return ln.LINE_NO === line.LINE_NO
        });
        toChange[0].GRPO_QTY = toChange[0].GRPO_QTY + line.GRPO_QTY;
    }
});

const lines = [{
        "LINE_NO": 15,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 160000,
        "GRPO_SHIPDATE": "September, 21 2017 00:00:00"
    },
    {
        "LINE_NO": 15,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 320800,
        "GRPO_SHIPDATE": "October, 07 2017 00:00:00"
    },
    {
        "LINE_NO": 15,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 19200,
        "GRPO_SHIPDATE": "October, 20 2017 00:00:00"
    },
    {
        "LINE_NO": 16,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 60000,
        "GRPO_SHIPDATE": "September, 13 2017 00:00:00"
    },
    {
        "LINE_NO": 16,
        "PO_QTY": 500000,
        "MATERIAL_NO": "130227",
        "MATERIAL_NAME": "T3-0381 Base Mold  φ10 M2",
        "GRPO_QTY": 440000,
        "GRPO_SHIPDATE": "October, 20 2017 00:00:00"
    }
]
const newLines = [],
    lineNumbers = [];
lines.forEach(line => {
    delete line.GRPO_SHIPDATE; /* delete shipdate */
    if (!lineNumbers.includes(line.LINE_NO)) {
        lineNumbers.push(line.LINE_NO); /* store current LINE_NO */
        newLines.push(line);
    } else {
        let toChange = newLines.filter(ln => { /* get current LINE_NO */
            return ln.LINE_NO === line.LINE_NO
        });
        toChange[0].GRPO_QTY = toChange[0].GRPO_QTY + line.GRPO_QTY;
    }
});

console.log(newLines)