У меня есть массив объектов, и я хочу объединить их в один объект, ЕСЛИ один из ключей соответствует (без перезаписи исходных свойств) - PullRequest
1 голос
/ 09 июля 2020

У меня есть массив объектов, и я хочу объединить их в один объект, ЕСЛИ один из ключей соответствует (в данном случае ключ «дата»)

    Array [
  Object {
    "date": "2020-07-14",
    "finishTime": "22:00",
    "startTime": "13:30",
  },
  Object {
    "date": "2020-07-14",
    "finishTime": "12:00",
    "startTime": "08:00",
  },
]

Ожидаемый результат должен быть

 Array [
  Object {
    "date": "2020-07-14",
    "finishTime": ["22:00", "12:00"]
    "startTime": ["13:30", "08:00"]
  },

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Вы можете написать общую c groupBy функцию, которая будет объединять объекты по полям. Пример:

const data = [
    {
      "date": "2020-07-14",
      "finishTime": "22:00",
      "startTime": "13:30",
    },
    {
      "date": "2020-07-14",
      "finishTime": "12:00",
      "startTime": "08:00",
    }
];


function groupBy(array, property) {
    const temp = {};
    for (const item of array) {
        const propValue = item[property];
        if (!temp.hasOwnProperty(propValue)) {
            temp[propValue] = {
                [property]: propValue 
            };
        }

        for (const [key, value] of Object.entries(item)) {
            if (key === property) continue;

            temp[propValue][key] = (temp[propValue][key] || []).concat(value);
        }
    }
    return Object.values(temp);
}

console.dir(groupBy(data, 'date'));

Вывод:

[
    {
        date: "2020-07-14",
        finishTime: ["22:00", "12:00"],
        startTime: ["13:30", "08:00"],
    }
]

В моем примере используется синтаксис ES6, если вам нужно, вы можете легко преобразовать этот код в ES5. Также мой код написан в императивном стиле, при необходимости его можно переписать с использованием reduce и forEach.

1 голос
/ 09 июля 2020

Logi c за решением:

  1. Создайте новый пустой массив (назовите его Y ), в котором мы будем хранить «компактное» решение.
  2. Цикл через все элементы исходного массива (назовите его X).
  3. Проверить, есть ли уже текущий элемент (из X ) в массиве Y , (найдите индекс из Y , чтобы элемент можно было обновить).
  4. Если индекс равен -1 , элемента нет, поэтому мы добавляем его к Y .
  5. В противном случае (элемент уже существует в Y ) мы получаем элемент, используя индекс (больше -1) -> update (с pu sh ) конец sh и время начала -> перепишите обновленный found_element в Y , используя найденный ранее индекс.

Вот рабочий пример:

// DATA
const data = [
  {
    "date": "2020-07-14",
    "finishTime": "22:00",
    "startTime": "13:30",
  },
  {
    "date": "2020-07-14",
    "finishTime": "12:00",
    "startTime": "08:00",
  }
];

// NEW_DATA
const new_data = [];

data.forEach(element => {
  const index = new_data.findIndex(el => el.date === element.date);
  
  if(index === -1) {
    // Not Found
    new_data.push({
      "date": element.date,
      "finishTime": [element.finishTime],
      "startTime": [element.startTime],
    });
  } else {
    // Found
    let found_element = new_data[index];
    
    found_element.finishTime.push(element.finishTime);
    found_element.startTime.push(element.startTime);
    
    new_data[index] = found_element;
  }
});

console.log(`NEW DATA: ${JSON.stringify(new_data)}`);

Надеюсь, это поможет :)

PS: Это очень простое c решение, вы должны реализовать своего рода проверку ошибок и проверку типов. Я предлагаю вам использовать Typescript:)

PS.PS: Как видите, исходный массив данных не был изменен :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...