JS使用includes()遍历对象数组如何返回最接近/精确匹配项
问题场景
需要对两个对象数组做字段匹配,从obj2中找到与obj1的address字段匹配度最高的street条目,仅返回最精确的匹配结果,不返回短子串的低精度匹配。
原有实现代码如下:
const obj1 = [ { name: "I am the one and only", address: "street name 123, 456" }, { name: "I am here only to fill up the place", address: "to not be a 1 element long array of objects"} ] const obj2 = [ { name: "testA", street: "street name 123" }, { name: "testB", street: "street name 1" }, { name: "testC", street: "street name" } ] for ( let i of obj1 ) { for ( let j of obj2 ) { if(i.address.includes(j.street)) { console.log(i, j) } } }
原有代码缺陷:仅判断street是否为address的子串,会同时返回street name 123、street name 1、street name三组匹配结果,不符合仅返回最高精度匹配的需求。
实现思路
街道、地址类的子串匹配中,匹配到的子串长度越长,匹配精度越高。不需要额外引入复杂的正则或相似度计算库,只需要在所有符合子串匹配规则的结果中,筛选出street字段长度最长的条目,即为当前address对应的最高匹配度结果。
可直接运行的实现代码
const obj1 = [ { name: "I am the one and only", address: "street name 123, 456" }, { name: "I am here only to fill up the place", address: "to not be a 1 element long array of objects"} ] const obj2 = [ { name: "testA", street: "street name 123" }, { name: "testB", street: "street name 1" }, { name: "testC", street: "street name" } ] const finalMatches = [] for (const addrItem of obj1) { // 先收集所有满足子串匹配的候选条目 const candidateMatches = obj2.filter(streetItem => addrItem.address.includes(streetItem.street)) if (candidateMatches.length === 0) continue // 从候选中选street长度最长的,即为最高精度匹配 const bestMatch = candidateMatches.reduce((maxLenItem, currentItem) => { return currentItem.street.length > maxLenItem.street.length ? currentItem : maxLenItem }) finalMatches.push({ addressEntry: addrItem, matchedStreetEntry: bestMatch }) } // 输出最终结果 console.log(finalMatches)
运行效果
代码执行后仅返回1组匹配结果:
- obj1匹配项:address值为
street name 123, 456的条目 - obj2匹配项:street值为
street name 123的testA条目
完全符合预期需求。
如果遇到多个street长度完全相同、同时匹配同一个address的边界场景,可以在reduce逻辑中追加自定义优先级规则,比如优先选择匹配起始位置更靠前的条目即可。
内容的提问来源于stack exchange,提问作者Dariusz Legizynski
相关产品推荐
相关产品推荐

