【问题标题】:Sum JSON Objects and remove duplicate from an array对 JSON 对象求和并从数组中删除重复项
【发布时间】:2021-05-12 21:54:32
【问题描述】:

我有以下对象数组:

const lineItems = [
  {
    "lineNumber": "0",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 5,
    "shippedQty": 10,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "1",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 40,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 4,
    "shippedQty": 20,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "2",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "receivedQty": 5,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "3",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "receivedQty": 10,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  }
];

期待输出:

[
  {
    "lineNumber": "0",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 50,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 9,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "2",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 20,
    "quantityUOM": "Unit",
    "receivedQty": 15,
    "shippedQty": 60,
    "itemCode": "Packagetest1"
  }
]

基于 batchNumber 和 item 值分组的数量、receivedQty 和 shippingQty 等属性的总和。前两个按批次编号和项目分组,但最后两个行项目仅按项目值分组。

groupedVariantLineItems() {
    let result = [];
    
    for( let i = 0; i < this.variantLineItems.length; i++ ) {
      let isExists = false;
      for( let j=0; j<result.length; j++ ) {
        if( typeof this.variantLineItems[i].batchNumber != "undefined" && result[j].batchNumber == this.variantLineItems[i].batchNumber && result[j].item == this.variantLineItems[i].item ) {
          isExists = true;
          result[j].quantity+= (this.variantLineItems[i].quantity!= undefined) ? Number(this.variantLineItems[i].quantity) : 0;
          result[j].shippedQty += (this.variantLineItems[i].shippedQty != undefined) ? Number(this.variantLineItems[i].shippedQty) : 0;
          result[j].receivedQty += (this.variantLineItems[i].receivedQty != undefined) ? Number(this.variantLineItems[i].receivedQty) : 0;

          result[j].quantity= ( isNaN(result[j].quantity) ) ? 0 : result[j].quantity;
          result[j].shippedQty = ( isNaN(result[j].shippedQty) ) ? 0 : result[j].shippedQty;
          result[j].receivedQty = ( isNaN(result[j].receivedQty) ) ? 0 : result[j].receivedQty;
          break;
        } else if( typeof this.variantLineItems[i].batchNumber == "undefined" && result[j].item == this.variantLineItems[i].item ) {
          isExists = true;
          result[j].quantity+= (this.variantLineItems[i].quantity!= undefined) ? Number(this.variantLineItems[i].quantity) : 0;
          result[j].shippedQty += (this.variantLineItems[i].shippedQty != undefined) ? Number(this.variantLineItems[i].shippedQty) : 0;
          result[j].receivedQty += (this.variantLineItems[i].receivedQty != undefined) ? Number(this.variantLineItems[i].receivedQty) : 0;

          result[j].quantity= ( isNaN(result[j].quantity) ) ? 0 : result[j].quantity;
          result[j].shippedQty = ( isNaN(result[j].shippedQty) ) ? 0 : result[j].shippedQty;
          result[j].receivedQty = ( isNaN(result[j].receivedQty) ) ? 0 : result[j].receivedQty;
          break;
        }
      }

      if( !isExists ) {
        result.push( this.variantLineItems[i] );
      }
    }

    return result;
  }

上面的代码给出了前两个具有批号的行项目的正确输出,但对于后两个不正确。

【问题讨论】:

  • 检查batchNumber属性是否存在并按其分组是否足够,如果不存在则按item属性分组?
  • 不,我这样做并创建了一个新对象,但它再次不起作用。感谢@Nermin 的认可

标签: javascript arrays json typescript ecmascript-6


【解决方案1】:
var stats = {quantity: 0};
lineItems.filter((line) => typeof line.batchNumber !== 'undefined').forEach((line) => stats.quantity += line.quantity);
console.log(stats); // {quantity: 50}

【讨论】:

  • 期望输出 JSON 数组
  • 你可以在forEach迭代器下检索你想要的任何东西,filter迭代器扮演where条件的角色,你可以在其中添加你的条件(未定义,..等)
【解决方案2】:

这不适合你吗?

const lineItems = [{
  "lineNumber": "0",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "batchNumber": "LO123678",
  "receivedQty": 5,
  "shippedQty": 10,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "1",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 40,
  "quantityUOM": "Unit",
  "batchNumber": "LO123678",
  "receivedQty": 4,
  "shippedQty": 20,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "2",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "receivedQty": 5,
  "shippedQty": 30,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "3",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "receivedQty": 10,
  "shippedQty": 30,
  "itemCode": "Packagetest1"
}
]

const sumMap = new Map()

for (entry of lineItems) {
  if (entry.batchNumber) {
    const batchAcc = sumMap.get(entry.batchNumber)

    if (batchAcc) {
      batchAcc.quantity += entry.quantity
      batchAcc.shippedQty += entry.shippedQty
      batchAcc.receivedQty += entry.receivedQty
    } else {
      sumMap.set(entry.batchNumber, entry)
    }
  } else {
    const itemAcc = sumMap.get(entry.item)

    if (itemAcc) {
      itemAcc.quantity += entry.quantity
      itemAcc.shippedQty += entry.shippedQty
      itemAcc.receivedQty += entry.receivedQty
    } else {
      sumMap.set(entry.item, entry)
    }
  }
}

const arr = Array.from(sumMap, ([, value]) => value)

console.log(arr)

我会在下一次编辑中制作一个更简洁的版本。

更简单的版本:

const properties = ['quantity', 'shippedQty', 'receivedQty']
const sumMap = new Map()

lineItems.forEach(entry => {
  const groupBy = entry.batchNumber ? entry.batchNumber : entry.item
  const acc = sumMap.get(groupBy)

  if (acc) {
    properties.forEach(property => acc[property] += entry[property])
  } else {
    sumMap.set(groupBy, entry)
  }
})

const arr = [...sumMap].map(([, value]) => value)

console.log(arr)

【讨论】:

    【解决方案3】:

    else if 条件如下:

    } else if( typeof this.variantLineItems[i].batchNumber == "undefined" && typeof result[j].batchNumber == "undefined" && result[j].item == this.variantLineItems[i].项目){

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-12
      • 2017-04-10
      • 1970-01-01
      相关资源
      最近更新 更多