Преобразование нескольких массивов объектов в один массив при объединении объектов по общему ключу - PullRequest
0 голосов
/ 02 ноября 2018

Итак, у меня есть массив объектов, который выглядит следующим образом.

const myArray = [
  {
    values: [
      { date: "2018-11-02", "value1": 3, "value2": 5 },
      { date: "2018-11-01", "value1": 8, "value2": 9 },
      { date: "2018-10-31", "value1": 4, "value2": 10 },
    ],
    customer: "Customer One"
  },
  {
    values: [
      { date: "2018-11-02", "value1": 3 },
      { date: "2018-11-01", "value1": 5 },
      { date: "2018-10-31", "value1": 8 },
    ],
    customer: "Customer Two"
  }
];

Все значения объекта должны суммироваться (по дате), а затем приводиться в качестве значения для клиента в новом объекте

Я хочу, чтобы это выглядело так:

result = [
  { date: "2018-11-02", "Customer One": 8, "Customer Two": 3 },
  { date: "2018-11-01", "Customer One": 17, "Customer Two": 5 },
  { date: "2018-10-31", "Customer One": 14, "Customer Two": 8 },
]

У меня есть рабочий код для этого, но он кажется слишком сложным для того, что мне нужно, но по какой-то причине я не могу обернуть голову более простым способом.

Вот мой код (также для кодов и ящиков: https://codesandbox.io/s/zvlpm167x):

const myArray = [
  {
    values: [
      { date: "2018-11-02", "value1": 3, "value2": 5 },
      { date: "2018-11-01", "value1": 8, "value2": 9 },
      { date: "2018-10-31", "value1": 4, "value2": 10 },
    ],
    customer: "Customer One"
  },
  {
    values: [
      { date: "2018-11-02", "value1": 3 },
      { date: "2018-11-01", "value1": 5 },
      { date: "2018-10-31", "value1": 8 },
    ],
    customer: "Customer Two"
  }
];

const flatArray = myArray.flat();

const sumObjectKeysExceptDate = object => Object.keys(object).reduce((sum, key) => {
  if (!Number.isNaN(parseInt(object[key], 10)) && key !== 'date') {
    return sum + parseInt(object[key], 10);
  }
  return sum;
}, 0);

const result = flatArray
  .reduce((acc, row) => [...acc, ...row.values.map(value => ({ [row.customer]: sumObjectKeysExceptDate(value), date: value.date }))], [])
  .reduce((acc, row) => {
    if (acc.find(innerrow => innerrow.date === row.date)) {
      return acc.map((innerrow) => {
        if (innerrow.date === row.date) {
          return { ...innerrow, ...row };
        }
        return innerrow;
      });
    }
    return [...acc, row];
  }, []);

console.log(result)

1 Ответ

0 голосов
/ 02 ноября 2018

Попробуйте выполнить

  • Создать объект с date в качестве ключа и соответствующий результирующий объект в качестве значения. И с помощью Object.values получаем окончательный результат
  • Чтобы построить объект, используйте Array.reduce для внешнего массива и для каждого значения внутреннего массива проверьте, существует ли запись для даты или нет в объекте. Если он существует, обновите его, а затем создайте новую запись в объекте.
  • Для каждого объекта во внутреннем массиве суммируйте значения всех ключей, кроме даты, и установите его в объекте, соответствующем ключу имени customer.

const myArray = [{values: [{ date: "2018-11-02", "value1": 3, "value2": 5 },{ date: "2018-11-01", "value1": 8, "value2": 9 },{ date: "2018-10-31", "value1": 4, "value2": 10 },],customer: "Customer One"},{values: [{ date: "2018-11-02", "value1": 3 },{ date: "2018-11-01", "value1": 5 },{ date: "2018-10-31", "value1": 8 },],customer: "Customer Two"}];

let result = Object.values(myArray.reduce((a,c) => {
  c.values.forEach(({date, ...rest}) => {
    a[date] = a[date] || {date};
    a[date][c.customer] = Object.values(rest).reduce((d,e) => d + e);
  });
  return a;
}, {}));
console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...