从数组中删除重复对象,但合并嵌套对象

3

目前有一个包含游戏发布信息的对象数组。然而,游戏可能会在多个平台上发布,这些平台会作为不同的对象出现在数组中。我希望通过比较游戏ID来删除重复的游戏,并合并平台对象。

我尝试使用reduce函数成功地通过游戏ID删除了重复对象,但我无法将其改编为合并平台。

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

如果不同平台的发布日期不同,应该怎么办?在这种情况下,“只狼:影逝二度”同时在多个平台上发布了他们的游戏。但是,推迟某些平台的游戏发布并不罕见。例如,“暗黑破坏神3”于2012年在Windows和OS X上发布,2013年在PS3上发布,2014年在PS4上发布,2018年在Switch上发布。 - 3limin4t0r
好的,我认为一个简单的操作符就可以解决这个用例。const x = acc.find(item => item.game.id === current.game.id && item.releaseDate == current.releaseDate); - Adam
4个回答

2
你离答案很近了,只需要稍微改变一下逻辑。你可以尝试像下面这个例子一样做: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
你可以将对象的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; }


0
请看一下:

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
这里是另一种解决方案,使用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));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接