对象数组中多个相似键的特定键的总和 - JavaScript

时间:2021-01-08 07:29:09

标签: javascript arrays object

我有一个对象数组,如下所示:

[
    {
        'Product': 'P1',
        'Price': 150,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 100,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2,
    },
    {
        'Product': 'P2',
        'Price': 10,
        'Location': 1,
    },
    {
        'Product': 'P2',
        'Price': 130,
        'Location': 1,
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    }
]

我需要将具有相同产品和相同位置的对象的所有价格相加。对于上面的示例,结果将是:

[
   {
        'Product': 'P1',
        'Price': 250, // price is the sum of both similar in location and product
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2, // same product but different location
    },
    {
        'Product': 'P2',
        'Price': 140, //sum of same
        'Location': 1, 
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    },
]

我搜索了几个类似的问题,但那些只处理一个要检查的密钥,我有不同的密钥(产品和位置 - 将来可能会超过 2 个)来识别不同。

3 个答案:

答案 0 :(得分:2)

const input = [
    {
        'Product': 'P1',
        'Price': 150,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 100,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2,
    },
    {
        'Product': 'P2',
        'Price': 10,
        'Location': 1,
    },
    {
        'Product': 'P2',
        'Price': 130,
        'Location': 1,
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    }
]

const output = []
input.forEach(item => {
  const index = output.findIndex(o => o.Product === item.Product && o.Location === item.Location);
  if (index === -1) {
    output.push(item);
  } else {
    output[index].Price += item.Price;
  }
});
console.log(output);


无箭头功能

input.forEach(function(item) {
  const index = output.findIndex(function(o) { return o.Product === item.Product && o.Location === item.Location});
  if (index === -1) {
    output.push(item);
  } else {
    output[index].Price += item.Price;
  }
});

答案 1 :(得分:2)

你可以使用reduce()来做到这一点,

obj = [
   {
        'Product': 'P1',
        'Price': 250, // price is the sum of both similar in location and product
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2, // same product but different location
    },
    {
        'Product': 'P2',
        'Price': 140, //sum of same
        'Location': 1, 
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    },
]

res = obj.reduce((prev, curr) => {
  index = prev.findIndex(item => item.Product=== curr.Product && item.Location === curr.Location);
  if(index > -1) {
    prev[index].Price += curr.Price;
  } else {
    prev.push(curr);
  }
  return prev;
}, []);

console.log(res);

答案 2 :(得分:0)

针对我的用例修改@William 的回答(已接受),因为它要在不支持 ES6 功能(findIndex 和箭头功能)的平台上运行,这可以在没有 findIndex 的情况下完成如下;

var input = [{
    'Product': 'P1',
    'Price': 150,
    'Location': 1,
  },
  {
    'Product': 'P1',
    'Price': 100,
    'Location': 1,
  },
  {
    'Product': 'P1',
    'Price': 200,
    'Location': 2,
  },
  {
    'Product': 'P2',
    'Price': 10,
    'Location': 1,
  },
  {
    'Product': 'P2',
    'Price': 130,
    'Location': 1,
  },
  {
    'Product': 'P3',
    'Price': 40,
    'Location': 1,
  }
]

var output = []
input.forEach(function(item) {
  var index = output.indexOf(output.filter(function(o) {
    return o.Product === item.Product && o.Location === item.Location
  })[0]); // note the [0] index here
  if (index === -1) {
    output.push(item);
  } else {
    output[index].Price += item.Price;
  }
});
console.log(output);