如何高效筛选sortKey中与receivedOrderKey部分匹配的元素?
如何高效筛选数组中与另一数组元素部分匹配的值?
我有两个数组:
const sortKey = ["invoiceDate-desc", "invoiceDate-asc", "location-asc", "location-desc", "orderId-asc", "orderId-desc", "invoiceId-asc", "invoiceId-desc", "type-asc", "type-desc", "total-asc", "total-desc"]; const receivedOrderKey = ["invoiceId", "orderId"];
我需要筛选出sortKey中所有包含receivedOrderKey里元素的值,最终结果应该是["invoiceId-desc", "invoiceId-asc", "orderId-asc", "orderId-desc"]。
目前我用双重for循环实现了需求:
const requestedOptions = []; for(i=0;i<sortKey.length;i++){ var str1 = sortKey[i].toLowerCase(); for(j=0;j<receivedOrderKey.length;j++){ var str2 = receivedOrderKey[j].toLowerCase(); if(str1.includes(str2)) { requestedOptions.push(sortKey[i]); } } }
但这种方式的时间复杂度是O(n*m),有没有更高效的实现方式?
更高效的实现思路
双重循环的问题在于每次检查都要遍历receivedOrderKey,当数组规模变大时效率会明显下降。我们可以通过将匹配关键词转为查找效率更高的数据结构,或者利用正则匹配来优化,把时间复杂度降到O(n)级别。
方法1:Set + filter + some(通用性强)
把receivedOrderKey转换成Set(查找时间复杂度O(1)),再结合数组的filter和some方法实现筛选:
const sortKey = ["invoiceDate-desc", "invoiceDate-asc", "location-asc", "location-desc", "orderId-asc", "orderId-desc", "invoiceId-asc", "invoiceId-desc", "type-asc", "type-desc", "total-asc", "total-desc"]; const receivedOrderKey = ["invoiceId", "orderId"]; // 提前把关键词转成小写并存入Set,避免重复转换 const lowerKeySet = new Set(receivedOrderKey.map(key => key.toLowerCase())); const requestedOptions = sortKey.filter(item => { const lowerItem = item.toLowerCase(); // 检查当前item是否包含Set中的任意一个关键词 return [...lowerKeySet].some(key => lowerItem.includes(key)); }); console.log(requestedOptions); // 输出: ["orderId-asc", "orderId-desc", "invoiceId-asc", "invoiceId-desc"]
方法2:正则表达式(适合关键词无特殊字符场景)
如果receivedOrderKey里的元素都是普通字符串(没有正则特殊字符,比如*、+等),可以用正则表达式简化代码:
const sortKey = ["invoiceDate-desc", "invoiceDate-asc", "location-asc", "location-desc", "orderId-asc", "orderId-desc", "invoiceId-asc", "invoiceId-desc", "type-asc", "type-desc", "total-asc", "total-desc"]; const receivedOrderKey = ["invoiceId", "orderId"]; // 生成匹配任意关键词的正则,开启忽略大小写模式 const matchRegex = new RegExp(receivedOrderKey.join('|'), 'i'); const requestedOptions = sortKey.filter(item => matchRegex.test(item)); console.log(requestedOptions); // 输出同样的目标结果
优化点说明
- Set方法:将
receivedOrderKey转为Set后,每次关键词查找的时间从O(m)降到O(1),整体筛选过程的时间复杂度为O(n)(n为sortKey的长度),数组规模越大,效率提升越明显。 - 正则方法:正则引擎内部经过高度优化,这种简单的"或匹配"效率很高,同时代码量更少、可读性更强。
- 另外你原来的代码存在全局变量污染问题(
i和j未用let/const声明),上面的优化方案也修复了这个问题。
内容的提问来源于stack exchange,提问作者Nightshade
相关产品推荐
相关产品推荐

