如何在JavaScript中同时获取filter()的结果与被移除元素?
更优的实现方案
你的需求是同时获取数组筛选后的结果和被移除的元素,现有实现虽然能达成目标,但复用性较差(硬编码了目标数组和判断逻辑),且可以通过更通用、高效的方式实现。
推荐方案1:使用reduce实现一次遍历的通用分割函数
reduce可以在单次遍历中完成分组,时间复杂度为O(n),是效率最高的方式之一,同时具备良好的复用性:
function splitArray(arr, predicate) { return arr.reduce((result, item) => { // 根据判断条件将元素推入对应的数组 result[predicate(item) ? 'passed' : 'failed'].push(item); return result; }, { passed: [], failed: [] }); // 初始化结果对象 } // 使用示例 const { passed, failed } = splitArray([1, 2, 3], num => num <= 1); console.log('筛选结果:', passed); // [1] console.log('被移除元素:', failed); // [2, 3]
推荐方案2:使用forEach手动遍历(更直观)
如果觉得reduce的逻辑不够直观,也可以用forEach做单次遍历,效率和reduce一致:
function splitArray(arr, predicate) { const passed = []; const failed = []; for (const item of arr) { if (predicate(item)) { passed.push(item); } else { failed.push(item); } } return { passed, failed }; } // 使用示例 const result = splitArray([1, 2, 3], num => num <= 1); console.log(result); // { passed: [1], failed: [2, 3] }
不推荐的方案:两次filter调用
虽然以下写法代码简洁,但会对数组进行两次遍历,大数据量下效率较低:
const arr = [1, 2, 3]; const passed = arr.filter(num => num <= 1); const failed = arr.filter(num => !(num <= 1));
总结
- 如果追求最高效率和通用性,优先选择
reduce或forEach的单次遍历方案; - 你的原始实现可以改造为通用函数,去掉硬编码的数组和判断逻辑,提升复用性。
内容的提问来源于stack exchange,提问作者kyw
相关产品推荐
相关产品推荐

