You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对比两个对象数组过滤非匹配项,保留数据库球员自定义Active状态

问题描述

我现在发起了两个GET 请求,一个请求本地数据库,另一个请求第三方API。

我手里有两个对象数组:数据库返回的数组存储球员数据,部分球员的Active状态被设置为true或false(我正在开发应用前端功能,支持用户控制球员是否启用);API返回的数组同样包含球员数据,但所有球员的Active状态默认均为true,该数据每24小时拉取一次,会通过PUT 请求发送到数据库并覆盖所有原有数据。

需求

如果数据库中某球员的Active状态为false,我需要在API返回的数组中忽略该对象,仅用'Active': true的球员数据更新数据库。

以下是数据库存储的数组示例:

[{
    "PlayerID": 12345,
    "Team": "ABC",
    "FirstName": "Patrick",
    "LastName": "Star",
    "Position": "RB",
    "Active": false,
    "__v": 0
},
{
    "PlayerID": 67890,
    "Team": "DEF",
    "FirstName": "Spongebob",
    "LastName": "Squarepants",
    "Position": "WR",
    "Active": true,
    "__v": 0
}]

以下是API返回的数组示例,请注意Patrick Star的Active状态为true:

[{
    "PlayerID": 12345,
    "Team": "ABC",
    "FirstName": "Patrick",
    "LastName": "Star",
    "Position": "RB",
    "Active": true,
    "__v": 0
},
{
    "PlayerID": 67890,
    "Team": "DEF",
    "FirstName": "Spongebob",
    "LastName": "Squarepants",
    "Position": "WR",
    "Active": true,
    "__v": 0
}]

我需要对比这两个数组,返回仅包含有效启用球员的新数组(上述示例中为Spongebob Squarepants),这样数据库中'Active': false的球员不会被更新覆盖。我打算用PlayerID作为参考字段区分球员并做过滤,但目前无法实现。

编辑:以下是我要实现该功能的现有代码:

function getPlayers() {
  const APIplayersURL = "someURL";
  const DBoffensivePlayersURL = "http://localhost:4000/api/offensiveplayers";

  axios.get(DBoffensivePlayersURL).then((res) => {
    const inactivePlayers = res.data;

    // Filter out all of the active players
    const dbArr = inactivePlayers.filter(
      players =>
        players.Active === false
    );
    
    axios.get(APIplayersURL).then((res) => {
      const players = res.data;

      // Filter out all players except for QB, RB and WR
      const offensivePlayers = players.filter(
        players =>
          players.Position === "QB" ||
          players.Position === "RB" ||
          players.Position === "WR"
      );
      
      // Give me all active QBs, RBs, and WRs
      const apiArr = offensivePlayers.filter(
        offensivePlayers =>
          offensivePlayers.Status === "Active"
      );
  
      const result = dbArr.filter(
        (obj) => obj.Active && apiArr.some((o) => o.PlayerID === obj.PlayerID)
      );
      
      console.log(result);

      const config = {
        headers: {
          "Content-Type": "application/json",
          "Authorization": "x-auth-token",
          "Access-Control-Allow-Origin": "*"
        },
      };
  
        axios
          .put("http://localhost:4000/api/offensiveplayers", result, config)
          .then((res) => console.log(res))
          .catch((err) => console.error(err));
        console.log("Players updated successfully");
      });
  });
}

// Runs the getPlayers every 24 hours
setInterval(getPlayers, 86400000);

解决方案

你现有代码的核心问题是逻辑搞反了:你从数据库拉取数据后,dbArr只保留了Active: false的球员,后续过滤又判断obj.Active,最终得到的result必然是空数组。

正确逻辑应该是:先提取数据库里所有禁用球员的PlayerID存为集合,再把API返回的合格球员中,属于禁用集合的球员剔除,剩下的就是要更新到数据库的数据。用Set存储禁用ID的查询效率比数组更高,数据量大的时候优势更明显。

修正后的代码如下:

function getPlayers() {
  const APIplayersURL = "someURL";
  const DBoffensivePlayersURL = "http://localhost:4000/api/offensiveplayers";

  axios.get(DBoffensivePlayersURL).then((res) => {
    const allDbPlayers = res.data;
    // 提取所有被禁用的球员ID,存入Set提升查询效率
    const inactivePlayerIds = new Set(
      allDbPlayers
        .filter(player => player.Active === false)
        .map(player => player.PlayerID)
    );
    
    axios.get(APIplayersURL).then((res) => {
      const apiPlayers = res.data;

      // 过滤出位置符合要求的进攻组球员
      const offensivePlayers = apiPlayers.filter(
        player => ["QB", "RB", "WR"].includes(player.Position)
      );
      
      // 过滤出API返回的状态为启用的球员
      const validApiPlayers = offensivePlayers.filter(
        player => player.Status === "Active"
      );

      // 剔除数据库中被禁用的球员,得到最终更新列表
      const result = validApiPlayers.filter(
        player => !inactivePlayerIds.has(player.PlayerID)
      );
      
      console.log(result);

      const config = {
        headers: {
          "Content-Type": "application/json",
          "Authorization": "x-auth-token",
          "Access-Control-Allow-Origin": "*"
        },
      };
  
      axios
        .put("http://localhost:4000/api/offensiveplayers", result, config)
        .then((res) => console.log(res))
        .catch((err) => console.error(err));
      console.log("球员更新成功");
    });
  });
}

// 每24小时执行一次getPlayers
setInterval(getPlayers, 86400000);

内容的提问来源于stack exchange,提问作者KyleOli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 11:00:01