Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove duplicate objects from an array but merge nested objects

Currently have an array of objects which contain game releases. However game releases can happen on multiple platforms and these appear as separate objects within the array. I'm looking to remove duplicate games by comparing the game id but merge the platforms object

I have tried using the reduce function which successfully removes duplicate objects by game id but I'm unable to adapt this to merge platforms

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;
  }
}, []);

Current Array:

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
}]

Expected format after merge:

[{
  "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
}]
like image 707
Adam Avatar asked Jul 26 '26 00:07

Adam


1 Answers

You were really close, you just need to change the logic a bit. You can try something like the following; an example - 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;
}, []);

The return value is

[
  {
    "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
  }
]

If you want to have just an array of platform strings, go with

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;
}, []);

And now the return value is

[
  {
    "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
  }
]
like image 136
EQuimper Avatar answered Jul 28 '26 12:07

EQuimper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!