
本文介绍两种简洁高效的方法,用于判断一个包含嵌套数组的对象数组中是否含有指定数值,重点使用 `some()` + `flat()` + `includes()` 组合及 `flatmap()` 链式展开技巧。
在实际开发中,我们常遇到类似这样的数据结构:一个对象数组,每个对象的值是数字数组(如天气代码映射),需快速判断某个目标数值(如 1003)是否存在于任意一个子数组中。直接遍历嵌套结构易出错且冗长,而现代 JavaScript 提供了更声明式、可读性更强的解决方案。
✅ 推荐方案一:some() + Object.values() + flat() + includes()
function weatherCodes() {
const codes = [{ sunny: [1001] }, { cloudy: [1002, 1003] }];
const theCode = 1003;
return codes.some(obj => Object.values(obj).flat().includes(theCode));
}
console.log(weatherCodes()); // true原理说明:
- codes.some(...) 遍历每个对象,只要有一个满足条件即返回 true;
- Object.values(obj) 提取对象所有属性值(此处为单个数组,如 [1001] 或 [1002, 1003]);
- .flat() 将值数组(本身已是数组)展平一层——即使对象含多层嵌套数组,.flat(1) 也能稳妥处理;
- .includes(theCode) 判断该扁平后数组是否含目标值。
✅ 优势:短小精悍、语义清晰、惰性求值(找到即停)、兼容性好(ES2019+)。
✅ 方案二:预展平后统一查询(flatMap + flat)
function weatherCodes() {
const codes = [{ sunny: [1001] }, { cloudy: [1002, 1003] }];
const theCode = 1003;
const allValues = codes.flatMap(obj => Object.values(obj)).flat();
return allValues.includes(theCode);
}
console.log(weatherCodes()); // true说明:
- flatMap(obj => Object.values(obj)) 先将每个对象转为值数组,再自动扁平一层(如 [[1001], [1002, 1003]] → [1001, 1002, 1003]);
- 外层 .flat() 是防御性处理:若某对象值本身是二维数组(如 {rainy: [[1004, 1005]]}),可确保彻底展平;
- 最终对完整一维数组执行 .includes()。
⚠️ 注意:此方式会完整展开所有数据,不具短路特性(即使首个元素就匹配,仍遍历全部),大数据量时略逊于方案一。
? 扩展建议
- 若需返回匹配的对象或键名,可改用 find() + entries():
const match = codes.find(obj => Object.entries(obj).some(([key, arr]) => arr.includes(theCode)) ); // → { cloudy: [1002, 1003] } - 兼容旧环境?可用 Array.prototype.reduce() 替代 flatMap,或引入 polyfill;
- 类型安全场景(如 TypeScript),建议为 codes 添加明确类型注解,避免 Object.values 返回 any[]。
总之,面对“对象数组中查找值”的需求,优先选用 some() 配合链式数组方法——既保持函数式风格,又兼顾性能与可维护性。










