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

Flutter中对比两个数组获取目标optid的实现方案(含非循环方法)

如何高效匹配两个数组的ID以获取对应的optid?

问题背景

我手头有两个数组,需要通过对比它们的id值,找到对应的optid。具体来说:
第一个数组(咱们叫它optArray)的结构是这样的:

[
  {
    "optid": "20",
    "ids": [
      { "id": "16", "desc": "test 1" },
      { "id": "12", "optionCode": "test 2" },
      { "id": "6", "optionCode": "test 3" }
    ]
  },
  {
    "optid": "22",
    "ids": [
      { "id": "20", "desc": "test 1" },
      { "id": "15", "optionCode": "test 2" },
      { "id": "6", "optionCode": "test 3" }
    ]
  },
  {
    "optid": "23",
    "ids": [
      { "id": "17", "desc": "test 1" },
      { "id": "2", "optionCode": "test 2" },
      { "id": "6", "optionCode": "test 3" }
    ]
  }
]

第二个数组(targetIdsArray)是:

[
  { "id": 17, "name": "test 1" },
  { "id": 2, "name": "test 2" },
  { "id": 6, "name": "tes t3" }
]

我的目标是找到**ids列表完全匹配第二个数组所有id**的那个optid(这里预期结果是23)。我知道嵌套循环能实现,但想找更高效的方案,有没有更好的办法?


优化方案推荐

核心思路是利用哈希结构(Set/Map)把查找复杂度从O(n)降到O(1),避免嵌套循环带来的性能浪费,尤其是数据量大的时候效果很明显。

方案1:单次查询最优——用Set快速校验匹配

先把目标数组的id转成字符串类型的Set(注意第一个数组里的id是字符串,第二个是数字,得统一类型),然后遍历optArray,检查每个元素的ids是否和目标Set完全匹配:

// 第一步:把目标ID转成字符串Set,方便快速查找
const targetIdSet = new Set(targetIdsArray.map(item => String(item.id)));

// 第二步:遍历optArray找匹配项
const matchedOptid = optArray.find(optItem => {
  // 把当前opt项的所有id也转成Set
  const optIdSet = new Set(optItem.ids.map(idItem => idItem.id));
  // 两个Set完全相等的条件:大小一致,且目标Set的所有元素都在当前Set里
  return optIdSet.size === targetIdSet.size && [...targetIdSet].every(id => optIdSet.has(id));
})?.optid;

console.log(matchedOptid); // 输出:"23"

这种方式的时间复杂度是O(n + m),比嵌套循环的O(n*m)高效很多。

方案2:多次查询最优——预构建映射表

如果需要多次做这类匹配查询,建议先提前构建一个optid到对应id集合的映射表,之后每次查询都能直接快速匹配:

// 预处理:构建optid到id集合的映射
const optIdMap = new Map();
optArray.forEach(optItem => {
  const idSet = new Set(optItem.ids.map(idItem => idItem.id));
  optIdMap.set(optItem.optid, idSet);
});

// 处理目标ID集合
const targetIdSet = new Set(targetIdsArray.map(item => String(item.id)));

// 查找匹配的optid
let matchedOptid = null;
for (const [optid, idSet] of optIdMap) {
  if (idSet.size === targetIdSet.size && [...targetIdSet].every(id => idSet.has(id))) {
    matchedOptid = optid;
    break;
  }
}

console.log(matchedOptid); // 输出:"23"

预处理只需要做一次,后续每次查询的成本都很低,适合频繁查询的场景。

方案3:简洁写法(小数据量适用)

如果数据量很小,也可以用更直观的写法,虽然效率不如前两种,但胜在代码简洁:

const targetIds = targetIdsArray.map(item => String(item.id));

const matchedOptid = optArray.find(optItem => {
  const optIds = optItem.ids.map(idItem => idItem.id);
  // 校验长度一致,且所有目标ID都在当前opt的ids里
  return targetIds.length === optIds.length && targetIds.every(id => optIds.includes(id));
})?.optid;

不过includes是O(n)的操作,数据量大的时候性能会下降,所以只推荐小数据场景用。


总结

  • 单次查询选方案1,兼顾效率和代码简洁度;
  • 多次查询选方案2,预处理一次后后续查询成本极低;
  • 小数据量可以用方案3,代码更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:37:50