简体   繁体   English

如何通过在Javascript中循环从数组中删除多个项目

[英]How to remove multiple items from an array via looping in Javascript

So, I have a javascript array of multiple values: 所以,我有一个包含多个值的javascript数组:

var keymap = {'name': 'foobaz', 
              'mappings': [{'id': 1, 'key': 'b'},
                          {'id': 2, 'key': 'c'},
                          {'id': 3, 'key': 'd'},
                          {'id': 1, 'key': 'e'},
                          {'id': 10, 'key': 'f'},
                          {'id': 7, 'key': 'g'},
                          {'id': 1, 'key': 'h'}]
}

I want to remove any entries where key is 'b'. 我想删除键为'b'的任何条目。 Note the ids correspond to the backend ids. 请注意,ID对应于后端ID。 What I want to do is to remove some of the mappings (for example, all with 'id' as '1'). 我想要做的是删除一些映射(例如,所有的'id'为'1')。

What I've tried is: 我试过的是:

for (var i = 0; i < keymap['mappings'].length; i++) {
    if (keymap['mappings'][i]['id'] === id_to_match) {
        keyboard_map['mappings'].splice(i, 1);
    }
}

However, slice will change the indexes of the array in-place, and therefore now i won't point to the correct index point (as any indexes higher will now be in where n would be the number of slices done before. 但是,slice将就地更改数组的索引,因此现在i不会指向正确的索引点(因为任何更高的索引现在将in其中n将是之前完成的切片数量。

What is the correct way to implement this? 实现这个的正确方法是什么?

An easy way is to decrement the iterator (this works since you read the length every iteration - so make sure you avoid caching the length) 一种简单的方法是减少迭代器(这是因为你每次迭代读取长度都有效 - 所以请确保你避免缓存长度)

for (var i = 0; i < keymap['mappings'].length; i++) {
 if (keymap['mappings'][i]['id'] === id_to_match) {
    keyboard_map['mappings'].splice(i, 1);
    i--;
 }
}

I would use the filter method: 我会使用过滤方法:

var id_to_remove = 1;
keymap.mappings = keymap.mappings.filter(function(item) {
    return item.id !== id_to_remove;
}));

Notice that, besides using the filter method or not, even with a plain for loop, is much better for performance create a new array from scratch, instead of mutate the current one multiple times. 请注意,除了使用filter方法之外,即使使用普通的for循环,性能要好得多,从头开始创建一个新数组,而不是多次改变当前的数组。 So basically: 所以基本上:

var id_to_remove = 1;
var filtered = [];
for (var i = 0, item; item = keymap.mappings[i++];) {
    if (item.id !== id_to_remove)
        filtered.push(item);
}
keymap.mappings = filtered;

Of course if filter is available it's much better use it because it's native, here we just mimic the same behavior. 当然,如果filter可用,它会更好地使用它,因为它是原生的,在这里我们只是模仿相同的行为。

for (var i = 0; i < keymap['mappings'].length; i++) {
    if (keymap['mappings'][i]['id'] === id_to_match) {
        keyboard_map['mappings'].splice(i--, 1);
    }
}

You could walk your array backwards, so that the splicing doesn't impact later loop iterations: 您可以向后移动数组,以便拼接不会影响以后的循环迭代:

for (var i = keymap['mappings'].length - 1; i >= 0; i--) {
    if (keymap['mappings'][i]['id'] === id_to_match) {
        keyboard_map['mappings'].splice(i, 1);
    }
}

You can use the "filter" method like this: 您可以像这样使用“过滤器”方法:

keymap.mappings = keymap.mappings.filter(function(element){
    return element.id != 1;
});

Which means "keep only elements with id different than 1" or same result "remove elements with id equal to 1". 这意味着“只保留id不同于1的元素”或相同结果“删除id等于1的元素”。

Every browser implement it, except IE8. 每个浏览器都实现它,IE8除外。 http://kangax.github.io/es5-compat-table/#Array.prototype.filter http://kangax.github.io/es5-compat-table/#Array.prototype.filter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM