объединение как объектов и значений с Array.reduce (} - PullRequest
1 голос
/ 19 апреля 2020

Я использую ваниль js для этой вспомогательной функции внутри приложения / машинописи реагирования. Json данные извлекаются, они содержат каждую букву алфавита, которой назначено значение и ключ. Они выложены в сетку плиток. Когда пользователь выбирает плитку, она добавляется в массив gameData в React, который используется для списка. Если пользователь нажимает на одну и ту же плитку, она объединяется, поэтому вместо нескольких элементов списка с одинаковыми значениями они объединяются с количеством + количество и значением + значение

Структура как таковая

const apiData = [
  {key: 'A', value: 50, quantity: 1, color: '#3498db', ...etc},
  {key: 'B', value: 40, quantity: 1, color: '#e67e22', ...etc},
  ...
]

const gameData = [
 {key: 'A', value: 200, quantity: 4, color: '#3498db', ...etc},
 {key: 'E', value: 10, color: '#fa0', ...etc},
]

export function groupBy(array: GameData[]) {
  const group: GameData[] = Object.values(
    array.reduce((acc: any, { value, quantity, ...r }) => {
      const key = Object.entries(r).join("-");
      acc[key] = acc[key] || { ...r, quantity: 0, value: 0 };
      return ((acc[key].value += value), (acc[key].quantity += 1)), acc;
    }, {})
  );
  return group;
}

Редуктор работает и сливается правильно, но я просто чувствую, что должен быть лучший способ сделать это. Есть идеи?

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Вы можете очистить вашу groupBy функцию уменьшения следующим образом:

function groupBy(data: GameData[]) {
    const result = data.reduce((total, item) => {
          const { key, value, quantity } =   item;
          const prevItem = total[key] || {};
          const {value: prevValue = 0, quantity: prevQuantity = 0} = prevItem;


          total[key]= {
                ...item,
                value: prevValue + value,
                quantity: prevQuantity + quantity,
          };

          return total;

    }, {});

    return Object.values(result);
}

Для данного входа он дает следующий результат:

const gameData = [
  {"key":"A","value":50,"quantity":1,"color":"#3498db"},
  {"key":"A","value":50,"quantity":1,"color":"#3498db"},
  {"key":"A","value":50,"quantity":1,"color":"#3498db"},
  {"key":"B","value":50,"quantity":1,"color":"#3498db"},
  {"key":"B","value":40,"quantity":1,"color":"#e67e22"}
];

const result = groupBy(gameData);
/*
result = [
  {"key":"A","value":150,"quantity":3,"color":"#3498db"},
  {"key":"B","value":90,"quantity":2,"color":"#e67e22"}
]
*/
1 голос
/ 19 апреля 2020

Ваше решение кажется нормальным, просто немного сложным для чтения. Вот мои предложения.

function groupBy(array){
    return Object.values(array.reduce((grouped, {value, quantity,...rest}) => {
        const key = Object.entries(rest).join('-');
        if(!grouped[key]){
            grouped[key] = {...rest, value: 0, quantity: 0};
        }
        grouped[key].quantity++;
        grouped[key].value += value;
        return grouped;
    },{}));
}

Или с помощью простого для:

function groupBy(array) {
    const grouped = {};
    for(let obj of array){
        const {value, quantity, ...rest} = obj;
        const key = Object.entries(rest).join('-');
        if(!grouped[key]){
            grouped[key]= {...rest, value: 0, quantity: 0};
        }
        grouped[key].quantity++;
        grouped[key].value+=value;
    }
    return Object.values(grouped);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...