如何捕获数组中被splice移除的元素及保留原数组的修改方案
嘿,我来帮你搞定这两个问题,一步步给你讲清楚~
1. 改进原函数,捕获被移除的元素
首先得说,你原来的函数有个小坑:用forEach的时候调用splice会导致数组长度变化,后面的元素会往前挪,这样有些符合条件的元素会被跳过(比如连续两个目标元素,第二个就可能没被处理到)。所以我们得调整循环方式,同时把被移除的元素存起来。
这里有个靠谱的实现,用反向for循环避免索引错位,同时收集被移除的元素:
function findAndRemove(array, property, value) { const removedItems = []; // 从数组末尾往前遍历,splice不会影响未遍历的元素索引 for (let index = array.length - 1; index >= 0; index--) { const item = array[index]; if (item[property] === value) { // splice返回被删除的元素数组,取第一个元素存入removedItems removedItems.push(array.splice(index, 1)[0]); } } // 返回收集到的被移除元素 return removedItems; }
使用示例
如果是对象数组(你的原函数是针对带属性的元素设计的):
const ar = [{id:1}, {id:2}, {id:3}, {id:4}, {id:5}]; // 移除id为1和2的元素 const removed1 = findAndRemove(ar, 'id', 1); const removed2 = findAndRemove(ar, 'id', 2); const ar1 = removed1.concat(removed2); console.log(ar); // 输出: [{id:3}, {id:4}, {id:5}] console.log(ar1); // 输出: [{id:1}, {id:2}]
如果是普通数组(比如你举的[1,2,3,4,5]),可以简化函数直接比较元素值:
function findAndRemovePlain(array, value) { const removedItems = []; for (let index = array.length - 1; index >= 0; index--) { if (array[index] === value) { removedItems.push(array.splice(index, 1)[0]); } } return removedItems; } const ar = [1,2,3,4,5]; const ar1 = findAndRemovePlain(ar, 1).concat(findAndRemovePlain(ar, 2)); console.log(ar); // 输出: [3,4,5] console.log(ar1); // 输出: [1,2]
2. 仅收集被移除元素,不修改原数组
你说尝试把元素推回原数组但没效果,其实根本不需要动原数组!我们只需要筛选出符合“要移除”条件的元素,原数组保持原样就好。这里有两种简单的实现方式:
方式1:forEach遍历收集(适配对象数组)
function getRemovedItems(array, property, value) { const removedItems = []; array.forEach(item => { if (item[property] === value) { removedItems.push(item); } }); return removedItems; }
方式2:用filter更简洁(推荐给普通数组)
function getRemovedItemsPlain(array, value) { return array.filter(item => item === value); }
使用示例
// 对象数组示例 const list = [{id:1}, {id:2}, {id:3}, {id:4}, {id:5}]; const removedItems = getRemovedItems(list, 'id', 1).concat(getRemovedItems(list, 'id', 2)); console.log(list); // 原数组完全不变: [{id:1}, {id:2}, {id:3}, {id:4}, {id:5}] console.log(removedItems); // 输出: [{id:1}, {id:2}] // 普通数组示例 const list = [1,2,3,4,5]; const removedItems = getRemovedItemsPlain(list, 1).concat(getRemovedItemsPlain(list, 2)); console.log(list); // 原数组完全不变: [1,2,3,4,5] console.log(removedItems); // 输出: [1,2]
这样就完全不会修改原数组,还能精准收集到你需要的元素啦~
内容的提问来源于stack exchange,提问作者Mark Jose
相关产品推荐
相关产品推荐

