I'm trying to delete all matched items from an array but it leaves Always one item in it.
var item1 = {item: "item1"},
array = [{
item: "item1"},{
item: "item_non"},{
item: "item1"},{
item: "item_non"},{
item: "item1"},{
item: "item1"},{
item: "item1"},{
item: "item_non"},{
item: "item_non"
}];
array.forEach(function(items){
if(item1.item === items.item){
var index = array.indexOf(items);
if(index !== -1){
array.splice(index,1);
}
}
});
I also fiddle it, it deletes only 4/5 items that matches instead of 5/5.
There is no option to use Array#filter
I need to delete the objects.
The problem is that .splice()
moves all the elements after the deleted element down. So if you delete element 3, element 4 becomes 3, 5, becomes 4, and so on. The next iteration of the loop will process element 4, but that's the original element 5 -- the original element 4 is skipped.
The way to solve this is to process the array in reverse. .forEach
can't do this, AFAIK, so you have to use a for
loop:
for (var i = array.length - 1; i >= 0; i--) {
item = array[i];
if (item1.item == item.item) {
array.splice(i, 1);
}
}
Here's another version that does in-place manipulation of the array.
http://codepen.io/anon/pen/XmZrww?editors=001
// remove the matching item and return the array
var filterArray = function (arr, obj) {
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i].item === obj.item) {
arr.splice(i, 1);
len--;
i--;
}
}
return arr;
};
var item1 = {item: "item1"};
var data = [
{item: "item1"},
{item: "item_non"},
{item: "item1"},
{item: "item_non"},
{item: "item1"},
{item: "item1"},
{item: "item1"},
{item: "item_non"},
{item: "item_non"}
];
console.log(filterArray(data, item1));
Here's my version http://codepen.io/anon/pen/VvQZVe?editors=001
Note I cleaned up the code a bit.
Repeatedly using indexOf in a loop is expensive. The worst case for doing that in a big array is having to go to almost the end of the loop many times.
This version potentially uses almost 2x the memory (imagine a big array where there's only a single item to be removed). But, its faster.
// indexOf is expensive, especially in a loop.
// here we just iterate straight through the array and append
// mismatching properties to another array that gets returned.
var filterArray = function (arr, obj) {
var returnArray = [];
arr.forEach(function (el) {
if (el.item !== obj.item) {
returnArray.push(el);
}
});
return returnArray;
};
var item1 = {item: "item1"};
var data = [
{item: "item1"},
{item: "item_non"},
{item: "item1"},
{item: "item_non"},
{item: "item1"},
{item: "item1"},
{item: "item1"},
{item: "item_non"},
{item: "item_non"}
];
console.log(filterArray(data, item1));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.