Как суммировать значения в массиве по заданному c ключу объекта? - PullRequest
5 голосов
/ 02 марта 2020

У меня есть массив 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"}
            ^^^^                ^^^^                ^^^^   

У меня проблемы с обдумыванием этого. Должен ли я сначала фильтровать, каким-то образом уменьшить его, переназначить его ... Я не знаю, с чего начать? Буду признателен за любую помощь, спасибо!

Ответы [ 3 ]

3 голосов
/ 02 марта 2020

Используйте Array.reduce, проверьте, существует ли объект с текущей страной, если он существует, от l oop до Object.keys, чтобы обновить значения, если нет, pu sh новое:

РЕДАКТИРОВАТЬ : если вам не нужен город, вы можете его разрушить {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);
0 голосов
/ 02 марта 2020

Используйте один forEach для массива и go для каждого ключа даты объекта, используя forEach, и создайте один объект res с уникальными ключами в виде Country и накопленными значениями. Используйте 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));
0 голосов
/ 02 марта 2020

Вы можете использовать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...