Prynik
@Prynik

Как объединить объекты в массиве, у которых повторяются значения одного поля?

Например, есть 3 объекта
const array = [
                    {
                        a: 'a',
                    },
                    {
                        a: 'a',
                        b: 'b'
                    },
                    {
                        a: 'a',
                        c: 'c'
                    }
                ]


На выходе должен получиться вот такой массив

[
                    {
                        a: 'a',
                        b: 'b',
                        c: 'c'
                    }
                ]
  • Вопрос задан
  • 443 просмотра
Решения вопроса 2
@Fallenyasha
Здесь могут быть более сложные варианты, например { a, b }, { b, c }, { c ,d }, { d ,e }, должен ли такой набор объектов схлопнуться в один { a, b, c, d, e }?

Опишу идею алгоритма:
0. на входе имеем
[ { a, b }, { b, c }, { c ,d }, { d ,e } ]
1. строим словарь из ключей и списка содержащих их объектов, т. е. должно получиться такое:
a: [ { a, b } ],
b: [ { a, b }, { b, c } ]
c: [ { b, c }, { c, d } ]
d: [ { c, d }, { d, e } ]
e: [ { d, e } ]
и строим второй словарь статусов
{ a, b }: 0
{ b, c }: 0
{ c ,d }: 0
{ d ,e }: 0
2. пробегаем в цикле по словарю и объединяем все объекты для каждого ключа, берем любой из объектов в каждом массиве и расширяем его, остальные удаляем из массива
a: [ { a, b } ], при изменении объекта при проходе b, он будет расширен до { a, b, c }
b: [ { a, b, c } ], например берем за основу { a, b } и расширяем до { a, b, c }, второй удаляем
c: [ { b, c, d } ], например берем за основу { b, c } и расширяем до { b, c, d }, второй удаляем
d: [ { c, d, e } ], например берем за основу { c, d } и расширяем до { c, d, e }, второй удаляем
e: [ { d, e } ], останется без изменений
в словаре статусов проснавляем для объединенных объектов признак объединения (1), для удаленных признак удаления (2), при этом правило выставления статуса должно быть 0->1, 0->2, 2->1
3. берем полученный набор значений как первоначальный массив объектов, при этом фильтруем по статусу, он не должен быть 2
[ { a, b, c }, { b, c, d }, { c, d, e } ]
4. в случае если на 2-м шаге объединять было нечего, то выходим, иначе переходим к шагу 1

Для оптимизации выполнения можно на 3-м шаге не просто фильтровать по статусу 2, но еще и отделять объекты со статусом 0, они в ходе прохода ни с чем не объединились, а значит больше их можно не трогать, перекладывать их в результирующий массив, а в следующий цикл входить только с объектами со статусом 1, и если таковых нет, то все
Ответ написан
Комментировать
const uniques = [...new Set(array.map(n => Object.keys(n)).flat())];
const convertToSingleObject = [uniques.reduce((acc, n) => ({ ...acc, [n]: n }), {})];
console.log(convertToSingleObject);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы