所以,我有一个包含多个值的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'}]
}
我想删除密钥为'b'的所有条目。请注意,ID对应于后端ID。我想要做的是删除一些映射(例如,所有'id'为'1')。
我尝试的是:
for (var i = 0; i < keymap['mappings'].length; i++) {
if (keymap['mappings'][i]['id'] === id_to_match) {
keyboard_map['mappings'].splice(i, 1);
}
}
但是,slice将就地更改数组的索引,因此现在i
将不会指向正确的索引点(因为任何更高的索引现在都是i-n
其中{{ 1}}将是之前完成的切片数量。
实现此目的的正确方法是什么?
答案 0 :(得分:5)
一种简单的方法是减少迭代器(这是因为你每次迭代读取长度都有效 - 所以请确保你避免缓存长度)
for (var i = 0; i < keymap['mappings'].length; i++) {
if (keymap['mappings'][i]['id'] === id_to_match) {
keyboard_map['mappings'].splice(i, 1);
i--;
}
}
答案 1 :(得分:2)
我会使用filter方法:
var id_to_remove = 1;
keymap.mappings = keymap.mappings.filter(function(item) {
return item.id !== id_to_remove;
}));
请注意,除了使用filter
方法之外,即使使用普通的for
循环,性能要好得多,从头开始创建一个新数组,而不是多次改变当前的数组。所以基本上:
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;
当然,如果filter
可用,那么使用它会好得多,因为它是原生的,在这里我们只是模仿相同的行为。
答案 2 :(得分:1)
for (var i = 0; i < keymap['mappings'].length; i++) {
if (keymap['mappings'][i]['id'] === id_to_match) {
keyboard_map['mappings'].splice(i--, 1);
}
}
答案 3 :(得分:1)
您可以向后移动数组,这样拼接不会影响以后的循环迭代:
for (var i = keymap['mappings'].length - 1; i >= 0; i--) {
if (keymap['mappings'][i]['id'] === id_to_match) {
keyboard_map['mappings'].splice(i, 1);
}
}
答案 4 :(得分:0)
您可以使用“filter”方法,如下所示:
keymap.mappings = keymap.mappings.filter(function(element){
return element.id != 1;
});
这意味着“只保留id不同于1的元素”或相同结果“删除id等于1的元素”。
每个浏览器都实现它,IE8除外。 http://kangax.github.io/es5-compat-table/#Array.prototype.filter