Javascript объединить массив объектов, без дубликатов - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть следующие данные:

// Data
const groups = [
    [
        { group: 'All', entries: 121, score: 10.89, grade: 16, avg: 15.8 },
        { group: 'All', entries: 221, score: 20.89, grade: 26, avg: 25.8 },
        { group: 'All', entries: 321, score: 30.89, grade: 36, avg: 35.8 },
        { group: 'All', entries: 421, score: 40.89, grade: 46, avg: 45.8 }
    ],

    [
        { group: 'Inner', entries: 121, score: 10.89, grade: 16, avg: 15.8 },
        { group: 'Inner', entries: 221, score: 20.89, grade: 26, avg: 25.8 },
        { group: 'Inner', entries: 321, score: 30.89, grade: 36, avg: 35.8 },
        { group: 'Inner', entries: 421, score: 40.89, grade: 46, avg: 45.8 }
    ],

    [
        { group: 'Outer', entries: 121, score: 10.89, grade: 16, avg: 15.8 },
        { group: 'Outer', entries: 221, score: 20.89, grade: 26, avg: 25.8 },
        { group: 'Outer', entries: 321, score: 30.89, grade: 36, avg: 35.8 },
        { group: 'Outer', entries: 421, score: 40.89, grade: 46, avg: 45.8 }
    ]
];

Мой желаемый результат:

// Desired
[
    [
        {
            group: 'All',
            entries0: 121,
            score0: 10.89,
            grade0: 16,
            avg0: 15.8,
            entries1: 121,
            score2: 10.89,
            grade2: 16,
            avg2: 15.8,
            entries3: 121,
            score3: 10.89,
            grade3: 16,
            avg3: 15.8,
            entries4: 121,
            score4: 10.89,
            grade4: 16,
            avg4: 15.8
        }
    ]
    ... all other groups formatted the same
];

Пожалуйста, кто-нибудь может указать мне правильное направление? Я пробовал множество вариантов, но мой код пока выглядит следующим образом:

groups.map((group) => {
    return Object.values(group).reduce((acc, curr) => {
        !acc.includes(curr.group) &&
            acc.push({
                group: curr.group,
                ...curr.score
            });

        return acc;
    });
});

Ответы [ 3 ]

2 голосов
/ 08 февраля 2020

Вот один вариант - для каждого группового массива введите запись group, затем flatMap записи внутренних объектов, взяв только ключи, не относящиеся к группе, и сопоставьте каждую запись, чтобы добавить индекс к каждому:

const groups = [
    [
        { group: 'All', entries: 121, score: 10.89, grade: 16, avg: 15.8 },
        { group: 'All', entries: 221, score: 20.89, grade: 26, avg: 25.8 },
        { group: 'All', entries: 321, score: 30.89, grade: 36, avg: 35.8 },
        { group: 'All', entries: 421, score: 40.89, grade: 46, avg: 45.8 }
    ],

    [
        { group: 'Inner', entries: 121, score: 10.89, grade: 16, avg: 15.8 },
        { group: 'Inner', entries: 221, score: 20.89, grade: 26, avg: 25.8 },
        { group: 'Inner', entries: 321, score: 30.89, grade: 36, avg: 35.8 },
        { group: 'Inner', entries: 421, score: 40.89, grade: 46, avg: 45.8 }
    ],

    [
        { group: 'Outer', entries: 121, score: 10.89, grade: 16, avg: 15.8 },
        { group: 'Outer', entries: 221, score: 20.89, grade: 26, avg: 25.8 },
        { group: 'Outer', entries: 321, score: 30.89, grade: 36, avg: 35.8 },
        { group: 'Outer', entries: 421, score: 40.89, grade: 46, avg: 45.8 }
    ]
];

const output = groups.map(
  groupArr => [Object.fromEntries([
    ['group', groupArr[0].group],
    ...groupArr.flatMap(
      (obj, i) => Object.entries(obj)
        .filter(([key]) => key !== 'group')
        .map(([key, val]) => [key + i, val])
      )
  ])]
);
console.log(output);
1 голос
/ 08 февраля 2020

Использование reduce и Object.entries. Это всего лишь небольшие изменения в вашем направлении.

const groups = [
  [
    { group: "All", entries: 121, score: 10.89, grade: 16, avg: 15.8 },
    { group: "All", entries: 221, score: 20.89, grade: 26, avg: 25.8 },
    { group: "All", entries: 321, score: 30.89, grade: 36, avg: 35.8 },
    { group: "All", entries: 421, score: 40.89, grade: 46, avg: 45.8 }
  ],

  [
    { group: "Inner", entries: 121, score: 10.89, grade: 16, avg: 15.8 },
    { group: "Inner", entries: 221, score: 20.89, grade: 26, avg: 25.8 },
    { group: "Inner", entries: 321, score: 30.89, grade: 36, avg: 35.8 },
    { group: "Inner", entries: 421, score: 40.89, grade: 46, avg: 45.8 }
  ],

  [
    { group: "Outer", entries: 121, score: 10.89, grade: 16, avg: 15.8 },
    { group: "Outer", entries: 221, score: 20.89, grade: 26, avg: 25.8 },
    { group: "Outer", entries: 321, score: 30.89, grade: 36, avg: 35.8 },
    { group: "Outer", entries: 421, score: 40.89, grade: 46, avg: 45.8 }
  ]
];

const updated = groups.map(group => [
  group.reduce(
    (acc, curr, i) =>
      Object.assign(
        acc,
        Object.fromEntries(
          Object.entries(curr).map(([key, value]) => [
            `${key}${key === "group" ? "" : i}`,
            value
          ])
        )
      ),
    {}
  )
]);

console.log(updated);
1 голос
/ 08 февраля 2020

Вы можете взять два вложенных цикла.

const
    groups = [[{ group: 'All', entries: 121, score: 10.89, grade: 16, avg: 15.8 }, { group: 'All', entries: 221, score: 20.89, grade: 26, avg: 25.8 }, { group: 'All', entries: 321, score: 30.89, grade: 36, avg: 35.8 }, { group: 'All', entries: 421, score: 40.89, grade: 46, avg: 45.8 }], [{ group: 'Inner', entries: 121, score: 10.89, grade: 16, avg: 15.8 }, { group: 'Inner', entries: 221, score: 20.89, grade: 26, avg: 25.8 }, { group: 'Inner', entries: 321, score: 30.89, grade: 36, avg: 35.8 }, { group: 'Inner', entries: 421, score: 40.89, grade: 46, avg: 45.8 }], [{ group: 'Outer', entries: 121, score: 10.89, grade: 16, avg: 15.8 }, { group: 'Outer', entries: 221, score: 20.89, grade: 26, avg: 25.8 }, { group: 'Outer', entries: 321, score: 30.89, grade: 36, avg: 35.8 }, { group: 'Outer', entries: 421, score: 40.89, grade: 46, avg: 45.8 }]],
    result = groups.map(a => a.reduce((r, { group, ...o }, i) => {
        r.group = group;
        Object.entries(o).forEach(([k, v]) => r[k + i] = v);
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...