如何在两个对象数组中查找匹配对象及相关扩展问题
数组对象匹配问题解决方案
问题1:从collectionData中找出与userData任意对象partido和categoria匹配的对象
原代码问题
你编写的compararObjetos函数存在逻辑缺陷:遍历userData时,第一次迭代就直接return过滤结果,导致仅处理了userData中的第一个对象,完全忽略后续的匹配条件。
正确实现
方案1:针对性匹配指定属性(partido + categoria)
通过生成匹配条件的唯一标识集合,快速过滤collectionData,性能更优:
function getMatchedCollection(userData, collectionData) { // 将userData的匹配条件转为唯一键集合 const matchKeys = new Set(userData.map(item => `${item.partido}|${item.categoria}`)); return collectionData.filter(item => { const currentKey = `${item.partido}|${item.categoria}`; return matchKeys.has(currentKey); }); } // 测试执行 const userData = [ { partido: 'Partido 8', categoria: '2'}, { partido: 'Partido 13', categoria: '3' } ]; const collectionData = [ { partido: 'Partido 8', Equipo_Local: 'Argentina', Equipo_Visitante: 'Arabia Saudí', categoria_1: '1', categoria: '2', Categoria_3: 'No disponible', }, { partido: 'Partido 24', Equipo_Local: 'Argentina', Equipo_Visitante: 'México', Categoria_1: 'Disponible', categoria: '2', Categoria_3: 'disponible', }, { partido: 'Partido 13', Equipo_Local: 'Polonia', Equipo_Visitante: 'Argentina', Categoria_1: 'No disponible', Categoria_2: 'No disponible', categoria: '3', }, ]; console.log(getMatchedCollection(userData, collectionData)); // 输出:包含Partido 8和Partido 13的两个collection对象
方案2:通用匹配userData所有属性
如果后续需要匹配userData对象的全部属性,可使用以下通用逻辑:
function getMatchedCollection(userData, collectionData) { return collectionData.filter(collectionItem => { return userData.some(userItem => { return Object.keys(userItem).every(key => collectionItem[key] === userItem[key]); }); }); }
问题2:返回userData中存在匹配的对象(排除无匹配项)
过滤userData,判断每个用户对象是否能在collectionData中找到属性匹配的项:
function getMatchedUsers(userData, collectionData) { return userData.filter(userItem => { return collectionData.some(collectionItem => { return Object.keys(userItem).every(key => collectionItem[key] === userItem[key]); }); }); } // 测试执行(使用问题1的数组) console.log(getMatchedUsers(userData, collectionData)); // 输出:完整的userData数组(两个对象均有匹配)
问题3:指定特定属性匹配,排查并修复原代码
原代码核心问题
- 匹配范围错误:遍历了用户对象的所有属性(包括
user_name、email),但pickedCollection仅包含指定的4个属性,导致额外属性的对比结果为undefined === 具体值,直接匹配失败。 - null值处理缺失:用户对象中的null属性未做特殊处理,直接参与对比会导致不匹配。
正确实现(匹配指定属性+处理null)
根据你预期匹配Tania和Vania的需求,逻辑为:指定属性中,用户不为null的属性必须与collection对象的对应属性相等,null属性跳过匹配。
function getMatchedUsersBySpecifiedProps(userData, collectionData, matchProps) { return userData.filter(user => { return collectionData.some(collectionItem => { return matchProps.every(prop => { const userVal = user[prop]; const collectionVal = collectionItem[prop]; // 用户值为null时跳过匹配,否则必须严格相等 return userVal === null || userVal === collectionVal; }); }); }); } // 测试执行 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: "12", categoria_1: "1", categoria_2: null, categoria_3: "3" }, { user_name: "Tom", email: "user-3@gmail.com", partido: "39", categoria_1: "1", categoria_2: null, categoria_3: null }, { user_name: "Vania", email: "user-4@gmail.com", partido: "13", categoria_1: null, categoria_2: null, categoria_3: "3" } ]; const collectionData = [ { partido: "8", Equipo_Local: "Argentina", Equipo_Visitante: "Arabia Saudí", categoria_1: "1", categoria_2: "No", categoria_3: "No" }, { partido: "24", Equipo_Local: "Argentina", Equipo_Visitante: "México", categoria_1: "No", categoria_2: "2", categoria_3: "No" }, { partido: "13", Equipo_Local: "Polonia", Equipo_Visitante: "Argentina", categoria_1: "No", categoria_2: "No", categoria_3: "3" } ]; const matchProps = ['partido', 'categoria_1', 'categoria_2', 'categoria_3']; console.log(getMatchedUsersBySpecifiedProps(userData, collectionData, matchProps)); // 输出:Tania和Vania的用户对象
原代码修复版本
如果要基于你原有的代码修改,调整如下:
function compareObjects(first, second) { let matches = []; const matchProps = ['partido', 'categoria_1', 'categoria_2', 'categoria_3']; second.forEach((possibleMatch) => { const pickedCollection = (({ partido, categoria_1, categoria_2, categoria_3 }) => ({ partido, categoria_1, categoria_2, categoria_3 }))(possibleMatch); first.forEach((user) => { const isMatch = matchProps.every((key) => { const userVal = user[key]; return userVal === null || userVal === pickedCollection[key]; }); // 用user_name判断是否已加入结果,避免重复 if (isMatch && !matches.find(match => match.user_name === user.user_name)) { matches.push(user); } }); }); return matches; } console.log(compareObjects(userData, collectionData));
内容的提问来源于stack exchange,提问作者Omar Giancarlo
相关产品推荐
相关产品推荐

