【问题标题】:How to sum values in array by specific object key?如何通过特定对象键对数组中的值求和?
【发布时间】:2020-06-14 21:45:45
【问题描述】:

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

var objArr = [
     {"Country": "US", "City": "MyCity1", "2017-07-12": "1", "2017-07-13": "2"},
     {"Country": "US", "City": "MyCity2", "2017-07-12": "2", "2017-07-13": "2"},
     {"Country": "CN", "City": "MyCity1", "2017-07-12": "5", "2017-07-13": "7"},
     {"Country": "CN", "City": "MyCity2", "2017-07-12": "5", "2017-07-13": "7"}
   ]

我想创建一个新数组,其中国家/地区是唯一的,但日期也应该相加。

{"Country": "US", "2017-07-12":  "3", "2017-07-13": "4"},
{"Country": "CN", "2017-07-12": "10", "2017-07-13": "14"}
            ^^^^                ^^^^                ^^^^   

我很难理解它。 我必须先过滤,以某种方式减少它,重新映射它,......我不知道开始吗? 任何帮助将不胜感激,谢谢!

【问题讨论】:

标签: javascript arrays object ecmascript-6 filter


【解决方案1】:

对数组使用一个forEach 并使用forEach 遍历每个对象的日期键,并使用唯一键为Country 和累积值构建一个res 对象。 使用 Object.values 的 res 从 res 对象中获取数组。

更新:修复以确保始终使用一种日期类型,即 number

var objArr = [
  { Country: "US", City: "MyCity1", "2017-07-12": "1", "2017-07-13": "2" },
  { Country: "US", City: "MyCity2", "2017-07-12": "2", "2017-07-13": "2" },
  { Country: "CN", City: "MyCity1", "2017-07-12": "5", "2017-07-13": "7" },
  { Country: "CN", City: "MyCity2", "2017-07-12": "5", "2017-07-13": "7" }
];

const update = data => {
  const res = {};
  data.forEach(({ Country, City, ...dates }) => {
    const item = res[Country] || { Country };
    Object.keys(dates).forEach(date => {
      item[date] = (item[date] || 0) + Number(dates[date]);
    });
    res[Country] = { ...item };
  });
  return Object.values(res);
};

console.log(update(objArr));

【讨论】:

  • 我的一些结果是字符串,有些是整数。这是正常的吗? ` 国家:“中国”3/1/20:79826 3/2/20:80026 1:国家:“泰国”2020 年 1 月 22 日:“2” 2020 年 1 月 23 日:“3”
  • @Jan,哦,我明白了。我认为最好有相同类型的物品。在这里我认为数字更好。我更新了答案以确保始终有数字。
【解决方案2】:

使用Array.reduce,检查当前国家的对象是否存在,如果存在,循环通过Object.keys更新值,如果不存在,推送一个新的:

编辑:如果你不想要 City,你可以解构它 {City, ...curr}

var objArr = [
  { Country: "US", City: "MyCity1", "2017-07-12": "1", "2017-07-13": "2" },
  { Country: "US", City: "MyCity2", "2017-07-12": "2", "2017-07-13": "2" },
  { Country: "CN", City: "MyCity1", "2017-07-12": "5", "2017-07-13": "7" },
  { Country: "CN", City: "MyCity2", "2017-07-12": "5", "2017-07-13": "7" }
];

var result = objArr.reduce((acc, {City, ...curr}) => {
  const ndx = acc.findIndex(e => e.Country === curr.Country);
  if (ndx > -1) {
    const [country, ...keys] = Object.keys(curr);
    keys.forEach(k => {
      acc[ndx][k] = +acc[ndx][k] + +curr[k];
    });
  } else {
    acc.push(curr);
  }
  return acc;
}, []);

console.log(result);

【讨论】:

  • Op 不想在结果中显示城市
【解决方案3】:

您可以使用reduce()创建一个对象来对元素进行分组,然后使用Object.values

var objArr = [
     {"Country": "US", "City": "MyCity1", "2017-07-12": "1", "2017-07-13": "2"},
     {"Country": "US", "City": "MyCity2", "2017-07-12": "2", "2017-07-13": "2"},
     {"Country": "CN", "City": "MyCity1", "2017-07-12": "5", "2017-07-13": "7"},
     {"Country": "CN", "City": "MyCity2", "2017-07-12": "5", "2017-07-13": "7"}
   ]

let keys = ["2017-07-12", "2017-07-13"];
const res = Object.values(objArr.reduce((ac, a) => {
  if(!ac[a.Country]){
    ac[a.Country] = {Country: a.Country};
  }

  keys.forEach(k => {
    ac[a.Country][k] = (ac[a.Country][k] || 0) + Number(a[k]);
  })
  return ac;
}, {}))
console.log(res)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    相关资源
    最近更新 更多