Bangsi Bangsi - 15 days ago 5
Javascript Question

JavaScript match array and splice but fails

I have

list
an array of
guid
values which will match the
guid
of
people
.

If
list
has the value of
'c7835c96-8dcc-b6e2-e452-494fe4d5fbc5'
then the below code should find

{
'guid': 'c7835c96-8dcc-b6e2-e452-494fe4d5fbc5',
'name': 'Stan Marsh'
}


and remove it from the array
people
and also from
list
.

The problem I have is that the script seems to stop after the first item and I can't figure how to get it to then loop through again to remove the next item in
list
.

jsFiddle Link

var list = ['c7835c96-8dcc-b6e2-e452-494fe4d5fbc5', '2d5ced81-5ee6-007b-de4c-bd3e5ab2c1fb'];
var people = [{
'guid': 'c7835c96-8dcc-b6e2-e452-494fe4d5fbc5',
'name': 'Stan Marsh'
},{
'guid': '6d1312f9-1cf3-dc23-c4f5-b216888d8641',
'name': 'Eric Cartman'
},{
'guid': '2d5ced81-5ee6-007b-de4c-bd3e5ab2c1fb',
'name': 'Kyle Brovlovski'
},{
'guid': '536a6f47-2049-5b1a-792c-11cc4f12b7c7',
'name': 'Kenny McCormick'
}
];

function arrayObjectIndexOf(myArray, searchTerm, property) {
for (var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i][property] === searchTerm) {
return i;
}
}
return -1;
}

list.filter(function(val) {
console.log(val);
var index = arrayObjectIndexOf(people, val, 'guid');
people.splice(index, 1);

var i = list.indexOf(val);
list.splice(i, 1);

console.info(people);
console.info(list);
});

console.log('=-----=');

Jon Jon
Answer

I suggest changing the code to the following:

list = list.filter(function(val) {
    var index = arrayObjectIndexOf(people, val, 'guid');
    if (index !== -1) {
        people.splice(index, 1);
    }
    return index == -1;
});

The problem with the original code was that, as Zoltán commented, it was modifying the list while iterating over it, so on the second iteration, the filter function decided it had already gone through all the items, since it was up to item [1] and the length of the array was now only 1.

There is no need to modify the list manually however because filter returns a new array containing the those items for which the callback returns true, so we just have to return true when the item is not found and assign filter's result back to list.

Another problem was that it was performing a splice even when the item was not found (a call to splice with the start parameter as -1 removes the last item from the array).