【问题标题】:Remove duplicate objects from an array but merge nested objects从数组中删除重复对象但合并嵌套对象
【发布时间】:2019-11-15 08:13:36
【问题描述】:

目前有一个包含游戏版本的对象数组。然而,游戏发布可能发生在多个平台上,并且这些在数组中显示为单独的对象。我希望通过比较游戏 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
}]

【问题讨论】:

  • 不同平台发布日期不同怎么办?在这种情况下,《只狼:Shadows Die Twice》同时在多个平台上发布了他们的游戏。但稍后为某些平台发布游戏的情况并不少见。以《暗黑破坏神3》为例,2012 年在 Windows 和 OS X 上发布,2013 年在 PS3 上发布,2014 年在 PS4 上发布,2018 年在 Switch 上发布。
  • 好点,我认为一个简单的操作员会解决这个用例。 const x = acc.find(item => item.game.id === current.game.id && item.releaseDate == current.releaseDate);

标签: javascript arrays object ecmascript-6


【解决方案1】:

你真的很接近,你只需要稍微改变一下逻辑。您可以尝试以下方法;一个例子 - 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
  }
]

【讨论】:

    【解决方案2】:

    您可以将对象的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; }

    【讨论】:

      【解决方案3】:

      请看一下:

      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);

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-15
          • 2020-12-07
          • 2021-12-28
          • 1970-01-01
          • 1970-01-01
          • 2021-08-23
          • 1970-01-01
          • 2020-08-02
          相关资源
          最近更新 更多