Удалить дубликаты объектов из массива, но объединить вложенные объекты - PullRequest
3 голосов
/ 04 июля 2019

В настоящее время есть массив объектов, которые содержат релизы игр. Однако релизы игр могут происходить на нескольких платформах, и они появляются как отдельные объекты в массиве. Я пытаюсь удалить дубликаты игр, сравнивая идентификатор игры, но объединяя объект платформы

Я пытался использовать функцию уменьшения, которая успешно удаляет дублирующиеся объекты по идентификатору игры, но я не могу адаптировать это для слияния платформ

const filteredArr = data.reduce((acc, current) => {
  const x = acc.find(item => item.game.id === current.game.id);

  if (!x) {
    return acc.concat([current]);
  } else {
    return acc;
  }
}, []);

Текущий массив:

const data = [{
  "id": 157283,
  "date": 1553212800,
  "game": {
    "id": 76882,
    "name": "Sekiro: Shadows Die Twice",
    "popularity": 41.39190295640344
  },
  "human": "2019-Mar-22",
  "m": 3,
  "platform": {"id": 48, "name": "PlayStation 4"},
  "region": 8,
  "y": 2019
}, {
  "id": 12,
  "date": 1553212800,
  "game": {
    "id": 76832,
    "name": "Spiderman",
    "popularity": 41.39190295640344
  },
  "human": "2019-Mar-22",
  "m": 3,
  "platform": {"id": 6, "name": "PC (Microsoft Windows)"},
  "region": 8,
  "y": 2019
}, {
  "id": 157283,
  "date": 1553212800,
  "game": {
    "id": 76882,
    "name": "Sekiro: Shadows Die Twice",
    "popularity": 41.39190295640344
  },
  "human": "2019-Mar-22",
  "m": 3,
  "platform": {"id": 48, "name": "Xbox"},
  "region": 8,
  "y": 2019
}]

Ожидаемый формат после слияния:

[{
  "id": 157283,
  "date": 1553212800,
  "game": {
    "id": 76882,
    "name": "Sekiro: Shadows Die Twice",
    "popularity": 41.39190295640344
  },
  "human": "2019-Mar-22",
  "m": 3,
  "platforms": ["PlayStation", "Xbox"],
  "region": 8,
  "y": 2019
}, {
  "id": 12,
  "date": 1553212800,
  "game": {
    "id": 76832,
    "name": "Spiderman",
    "popularity": 41.39190295640344
  },
  "human": "2019-Mar-22",
  "m": 3,
  "platforms": ["Playstation"],
  "region": 8,
  "y": 2019
}]

Ответы [ 4 ]

2 голосов
/ 04 июля 2019

Вы были действительно близки, вам просто нужно немного изменить логику. Вы можете попробовать что-то вроде следующего; пример - https://repl.it/@EQuimper/ScaryBumpyCircle

const filteredArr = data.reduce((acc, current) => {
  const x = acc.find(item => item.game.id === current.game.id);

  if (!x) {
    current.platform = [current.platform]
    acc.push(current);
  } else {
    x.platform.push(current.platform);
  }

  return acc;
}, []);

Возвращаемое значение

[
  {
    "id": 157283,
    "date": 1553212800,
    "game": {
      "id": 76882,
      "name": "Sekiro: Shadows Die Twice",
      "popularity": 41.39190295640344
    },
    "human": "2019-Mar-22",
    "m": 3,
    "platform": [
      {
        "id": 48,
        "name": "PlayStation 4"
      },
      {
        "id": 48,
        "name": "Xbox"
      }
    ],
    "region": 8,
    "y": 2019
  },
  {
    "id": 12,
    "date": 1553212800,
    "game": {
      "id": 76832,
      "name": "Spiderman",
      "popularity": 41.39190295640344
    },
    "human": "2019-Mar-22",
    "m": 3,
    "platform": [
      {
        "id": 6,
        "name": "PC (Microsoft Windows)"
      }
    ],
    "region": 8,
    "y": 2019
  }
]

Если вы хотите иметь только массив строк платформы, используйте

const filteredArr = data.reduce((acc, current) => {
  const x = acc.find(item => item.game.id === current.game.id);

  if (!x) {
    current.platform = [current.platform.name]
    acc.push(current);
  } else {
    x.platform.push(current.platform.name);
  }

  return acc;
}, []);

А теперь возвращаемое значение

[
  {
    "id": 157283,
    "date": 1553212800,
    "game": {
      "id": 76882,
      "name": "Sekiro: Shadows Die Twice",
      "popularity": 41.39190295640344
    },
    "human": "2019-Mar-22",
    "m": 3,
    "platform": [
      "PlayStation 4",
      "Xbox"
    ],
    "region": 8,
    "y": 2019
  },
  {
    "id": 12,
    "date": 1553212800,
    "game": {
      "id": 76832,
      "name": "Spiderman",
      "popularity": 41.39190295640344
    },
    "human": "2019-Mar-22",
    "m": 3,
    "platform": [
      "PC (Microsoft Windows)"
    ],
    "region": 8,
    "y": 2019
  }
]
0 голосов
/ 04 июля 2019

Вот еще одно решение, использующее forEach вместо reduce. При этом используется поисковый хеш, который ускоряет работу с большими объемами данных, чем при использовании find.

const data = [{"id": 157283, "date": 1553212800, "game": {"id": 76882, "name": "Sekiro: Shadows Die Twice", "popularity": 41.39190295640344}, "human": "2019-Mar-22", "m": 3, "platform": {"id": 48, "name": "PlayStation 4"}, "region": 8, "y": 2019}, {"id": 12, "date": 1553212800, "game": {"id": 76832, "name": "Spiderman", "popularity": 41.39190295640344}, "human": "2019-Mar-22", "m": 3, "platform": {"id": 6, "name": "PC (Microsoft Windows)"}, "region": 8, "y": 2019}, {"id": 157283, "date": 1553212800, "game": {"id": 76882, "name": "Sekiro: Shadows Die Twice", "popularity": 41.39190295640344}, "human": "2019-Mar-22", "m": 3, "platform": {"id": 48, "name": "Xbox"}, "region": 8, "y": 2019}];

let result = {};

data.forEach(({platform, ...release}) => {
  release.platforms = [platform.name];

  const releaseLookup = result[release.game.id];
  if (!releaseLookup) {
    result[release.game.id] = release;
  } else {
    releaseLookup.platforms.push(...release.platforms);
  }
});

console.log(Object.values(result));
0 голосов
/ 04 июля 2019

Пожалуйста, посмотрите:

const data = [    {        "id": 157283,
        "date": 1553212800,
        "game": {
            "id": 76882,
            "name": "Sekiro: Shadows Die Twice",
            "popularity": 41.39190295640344
        },
        "human": "2019-Mar-22",
        "m": 3,
        "platform": {
            "id": 48,
            "name": "PlayStation 4"
        },
        "region": 8,
        "y": 2019
    },
    {
        "id": 12,
        "date": 1553212800,
        "game": {
            "id": 76832,
            "name": "Spiderman",
            "popularity": 41.39190295640344
        },
        "human": "2019-Mar-22",
        "m": 3,
        "platform": {
            "id": 6,
            "name": "PC (Microsoft Windows)"
        },
        "region": 8,
        "y": 2019
    },{        "id": 157283,
    "date": 1553212800,
    "game": {
        "id": 76882,
        "name": "Sekiro: Shadows Die Twice",
        "popularity": 41.39190295640344
    },
    "human": "2019-Mar-22",
    "m": 3,
    "platform": {
        "id": 48,
        "name": "Xbox"
    },
    "region": 8,
    "y": 2019
},
]

const filteredArr = data.reduce((acc, current) => {
  const x = acc.find(item => item.game.id === current.game.id);
    if (!x) {
      current.platform = [current.platform.name]
      return acc.concat([current]);
    } else {
      x.platform.push(current.platform.name);
      return acc;
    }
  }, []);
console.log(filteredArr);
0 голосов
/ 04 июля 2019

Вы можете отделить platform от объекта и посмотреть, есть ли у вас объект с таким же id и добавить платформу для массива, чтобы не создавать новый набор данных.

const
    data = [{ id: 157283, date: 1553212800, game: { id: 76882, name: "Sekiro: Shadows Die Twice", popularity: 41.39190295640344 }, human: "2019-Mar-22", m: 3, platform: { id: 48, name: "PlayStation 4" }, region: 8, y: 2019 }, { id: 12, date: 1553212800, game: { id: 76832, name: "Spiderman", popularity: 41.39190295640344 }, human: "2019-Mar-22", m: 3, platform: { id: 6, name: "PC (Microsoft Windows)" }, region: 8, y: 2019 }, { id: 157283, date: 1553212800, game: { id: 76882, name: "Sekiro: Shadows Die Twice", popularity: 41.39190295640344 }, human: "2019-Mar-22", m: 3, platform: { id: 48, name: "Xbox" }, region: 8, y: 2019 }],
    result = data.reduce((r, { platform, ...o }) => {
        var temp = r.find(({ id }) => id === o.id);
        if (!temp) r.push(temp = { ...o, platforms: [] });
        temp.platforms.push(platform);
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...