Reputation: 6503
So, I have a javascript array of multiple values:
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'. Note the ids correspond to the backend ids. What I want to do is to remove some of the mappings (for example, all with 'id' as '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 i-n
where n
would be the number of slices done before.
What is the correct way to implement this?
Upvotes: 3
Views: 148
Reputation: 25322
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. 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.
Upvotes: 2
Reputation: 62
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".
Every browser implement it, except IE8. http://kangax.github.io/es5-compat-table/#Array.prototype.filter
Upvotes: 0
Reputation: 15397
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);
}
}
Upvotes: 1
Reputation: 3411
for (var i = 0; i < keymap['mappings'].length; i++) {
if (keymap['mappings'][i]['id'] === id_to_match) {
keyboard_map['mappings'].splice(i--, 1);
}
}
Upvotes: 1
Reputation: 82267
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--;
}
}
Upvotes: 5