js两个嵌套的循环如何让数值正确的删除

var patt = new RegExp(11);
var data = [
    [
        {a:1,b:1},
        {a:2,b:2},
        {a:3,b:3}
    ],
    [
        {a:11,b:11},
        {a:22,b:22},
        {a:33,b:33}
    ]
]
data.forEach((item,index) => { 
    item.forEach((item2,index2) => {
        if(!patt.test(item2.a)) {
            console.log(item2.a); //打印出的结果是1,2,3,22,33(除了11以外的所有项)
            item.splice(index2,1); //问题出在这一句
        }
    })
});
console.log(data); //我希望这个data能拿到的是{a:11,b:11}这一条数据

如上面的代码所示,我现在希望data打印出的结果是patt筛选的那个结果所在的那条数据{a:11,b:11}
该怎么修改这一段代码,让它能正确的打印出我想要的结果?

阅读 3.5k
4 个回答

item2.splice(index2,1); //item2
item是外层的,你要删除的是内层的。所以是item2**

仔细一看,我应该写错了。我再改改

forEach() 方法对数组的每个元素执行一次提供的函数。
应用场景:为一些相同的元素,绑定事件处理器!

那么forEach看上去不那么适合

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

filter()也不适合,他只有两个操作,要或者不要,所以最外层的循环他改变不了

map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

这个我觉得就还好了,因为他是一个返回值的合集

var patt = new RegExp(11);
var data = [
    [
        {a:1,b:1},
        {a:2,b:2},
        {a:3,b:3}
    ],
    [
        {a:11,b:11},
        {a:22,b:22},
        {a:33,b:33}
    ]
]
data = data.map((item,index) => { 
    item = item.filter((item2,index2) => {
        console.log(item2)
        return patt.test(item2.a)
    });
    return item
});
console.log(data); //我希望这个data能拿到的是{a:11,b:11}这一条数据

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。

该方法会改变原始数组。
var patt = new RegExp(11);
var data = [
    [
        {a:1,b:1},
        {a:2,b:2},
        {a:3,b:3}
    ],
    [
        {a:11,b:11},
        {a:22,b:22},
        {a:33,b:33}
    ]
]
data.forEach((item,index) => { 
    item.forEach((item2,index2) => {
        if(!patt.test(item2.a)) {
            console.log(data);
            item.splice(index2,1);
        }
    })
});

看看每次循环打印的data是什么。
每次在循环中进行splice操作时,都改变了data,也就是去掉一个item2,那么进行下一次循环的时候,由于少了一项,index2可能就取不到了(数组里只有两个项,但你想去下表为3的项)。所以造成了这个问题

记下位置,再从后往前删除;或者直接从后往前删除

换个思路呗
不改变原数组

Array.prototype.concat.apply(data).map(item => patt.test(item.a))
推荐问题
宣传栏