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

如何匹配两对象数组指定键并返回符合要求的结构化结果

用户与赛事数据的匹配逻辑优化

数据定义

用户数据数组

const userData = [
    {
      user_name: "Tania",
      email: "user-1@gmail.com",
      partido: "8",
      categoria_1: "1",
      categoria_2: "2",
      categoria_3: null
    },
    {
      user_name: "Jean",
      email: "user-2@gmail.com",
      partido: "24",
      categoria_1: null,
      categoria_2: "2",
      categoria_3: null
    },
    {
      user_name: "Vania",
      email: "user-4@gmail.com",
      partido: "13",
      categoria_1: null,
      categoria_2: "2",
      categoria_3: null
    },
    {
      user_name: "Rick",
      email: "user-4@gmail.com",
      partido: "13",
      categoria_1: "1",
      categoria_2: "2",
      categoria_3: "3"
    }
];

赛事集合数据数组

(修正原代码语法错误:categoria_1: ""No dis"改为categoria_1: "No dis")

const collectionData = [
    {
      partido: "8",
      Equipo_Local: "Argentina",
      Equipo_Visitante: "Arabia Saudí",
      categoria_1: "1",
      categoria_2: "No dis",
      categoria_3: "No dis"
    },
    {
      partido: "24",
      Equipo_Local: "Argentina",
      Equipo_Visitante: "México",
      categoria_1: "No dis",
      categoria_2: "2",
      categoria_3: "No dis"
    },
    {
      partido: "13",
      Equipo_Local: "Polonia",
      Equipo_Visitante: "Argentina",
      categoria_1: "No dis",
      categoria_2: "2",
      categoria_3: "3"
    }
];

数据特性

  • 两个数组的所有对象均包含partido、categoria_1、categoria_2、categoria_3属性,还可包含其他属性;
  • 上述属性值会动态变化。

现有匹配代码

现有代码尝试先按partido匹配,再依次匹配各分类,但输出不符合需求:

const checkPartido = ["partido"]
const checkCategoria_1 = ["categoria_1"]
const checkCategoria_2 = ["categoria_2"]
const checkCategoria_3 = ["categoria_3"]

function getMatches(
  first,
  second,
  checkPartido,
  checkCategoria_1,
  checkCategoria_2,
  checkCategoria_3) {

  let finalMatches = []
  let matchPartido = []
  let matchCat_1 = []
  let matchCat_2 = []
  let matchCat_3 = []

  first.forEach((userMatch) => {
    second.forEach((collection) => {
      const isMatchPartido = checkPartido.every((key) => {
        return collection[key] === userMatch[key];
      });
      if (
        isMatchPartido &&
        !matchPartido.find((match) => match === userMatch)
      ) {
        matchPartido.push(userMatch);
      }
    });
  });

  matchPartido.forEach((userMatch) => {
    second.forEach((newCollection) => {
      const isMatchCategory = checkCategoria_1.every((key) => {
        return newCollection[key] === userMatch[key]
      });
      if (
        isMatchCategory &&
        !matchCat_1.find((match) => {
          return match === userMatch
        })
      ) {
        matchCat_1.push(userMatch)
        return matchCat_1
      }
    });
  });

  matchCat_1.forEach((userMatch) => {
    second.forEach((newCollection) => {
      const isMatchCategory = checkCategoria_2.every((key) => {
        return newCollection[key] === userMatch[key]
      });
      if (
        isMatchCategory &&
        !matchCat_2.find((match) => {
          return match === userMatch
        })
      ) {
        matchCat_2.push(userMatch)
        return matchCat_2
      }
    });
  });

  matchCat_2.forEach((userMatch) => {
    second.forEach((newCollection) => {
      const isMatchCategory = checkCategoria_3.every((key) => {
        return newCollection[key] === userMatch[key]
      });
      if (
        isMatchCategory &&
        !matchCat_3.find((match) => {
          return match === userMatch
        })
      ) {
        matchCat_3.push(userMatch)
        return matchCat_3
      }
    });
  });

  return (finalMatches = [...matchCat_1, matchCat_2, matchCat_3])
}
// 注:原调用函数名错误,应为getMatches
console.log(
  getMatches(
    userData,
    collectionData,
    checkPartido,
    checkCategoria_1,
    checkCategoria_2,
    checkCategoria_3
  )
)

预期匹配规则

  1. 对partido: "8",匹配到1个用户(Tania),其categoria_1与赛事对应值匹配,返回包含该用户精简信息(user_name、email)的数组;
  2. 对partido: "24",匹配到1个用户(Jean),其categoria_2与赛事对应值匹配,返回对应精简数组;
  3. 对partido: "13",匹配到2个用户(Vania的categoria_2匹配,Rick的categoria_3匹配),返回对应精简对象数组。

解决方案

优化后的匹配函数

function getMatchedUsers(userData, collectionData) {
  // 将赛事数据按partido映射,提升查找效率
  const collectionMap = new Map();
  collectionData.forEach(item => {
    collectionMap.set(item.partido, item);
  });

  // 按partido分组存储匹配的用户精简信息
  const result = {};

  userData.forEach(user => {
    const partido = user.partido;
    const collectionItem = collectionMap.get(partido);
    if (!collectionItem) return;

    // 检查是否有任意一个categoria匹配(用户值不为null且与赛事值相等)
    const isMatched = 
      (user.categoria_1 !== null && user.categoria_1 === collectionItem.categoria_1) ||
      (user.categoria_2 !== null && user.categoria_2 === collectionItem.categoria_2) ||
      (user.categoria_3 !== null && user.categoria_3 === collectionItem.categoria_3);

    if (isMatched) {
      // 生成用户精简信息
      const simplifiedUser = {
        user_name: user.user_name,
        email: user.email
      };
      // 按partido分组添加结果
      if (!result[partido]) {
        result[partido] = [];
      }
      result[partido].push(simplifiedUser);
    }
  });

  return result;
}

// 调用函数并输出结果
console.log(getMatchedUsers(userData, collectionData));

输出结果

{
  "8": [
    { user_name: "Tania", email: "user-1@gmail.com" }
  ],
  "24": [
    { user_name: "Jean", email: "user-2@gmail.com" }
  ],
  "13": [
    { user_name: "Vania", email: "user-4@gmail.com" },
    { user_name: "Rick", email: "user-4@gmail.com" }
  ]
}

逻辑说明

  1. 赛事数据映射:用Map存储赛事数据,避免嵌套循环查找,提升运行效率;
  2. 匹配逻辑:对每个用户,先找到对应partido的赛事项,只要用户的某一categoria值不为null且与赛事对应值相等,即判定为匹配;
  3. 结果分组:按partido分组存储匹配的用户精简信息,完全符合预期输出结构;
  4. 精简信息:只保留user_name和email字段,满足需求中的精简要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:30:56