I need to find an object in array based on array of values and then remove them, this was easy when I only needed to find one item, I did it like this:
if (mdl.findObjectByKey(response, 'cat_id', 171) == true) {
console.log("item removed from dropdown");
var catId = response.map(item => item.cat_id).indexOf(171);
response.splice(catId, 1);
}
This would remove the item with a cat_id === 171 from the array of objects.
Now I need to remove more items so it would look something like this:
var itemsToRemove = [171, 182, 199, 234];
if (mdl.findObjectByKey(response, 'cat_id', itemsToRemove) == true) {
console.log("item removed from dropdown");
var catId = response.map(item => item.cat_id).indexOf(itemsToRemove);
response.splice(catId, 1);
}
Obviously, the above example does not work at all, I just wanted to explain what I needed.
-
Possible duplicate of javascript delete from array based on another array with same object and valuesHeretic Monkey– Heretic Monkey2018年03月13日 20:25:10 +00:00Commented Mar 13, 2018 at 20:25
-
Loop through the array and run the code you already have inside that array...Heretic Monkey– Heretic Monkey2018年03月13日 20:25:38 +00:00Commented Mar 13, 2018 at 20:25
-
You can also use filter functionBunnyDhaliwal– BunnyDhaliwal2018年03月13日 20:27:56 +00:00Commented Mar 13, 2018 at 20:27
-
You're finding an object, mapping the objects to a value, then searching that result for an index to remove. Seems like a lot of work for what could be done with a single function.user9366559– user93665592018年03月13日 20:29:14 +00:00Commented Mar 13, 2018 at 20:29
2 Answers 2
You're doing multiple passes just to remove a single object. You certainly don't want to keep it that way, much less duplicate all those passes for each key to remove.
Just filter the collection down to those without the keys to remove. Use a Set to avoid a repeated linear search.
var itemsToRemove = new Set([171, 182, 199, 234]);
var filtered = response.filter(obj => !itemsToRemove.has(obj.cat_id));
If you need to mutate the original collection, you can then copy it over.
filtered.forEach((obj, i) => response[i] = obj);
response.length = filtered.length;
You could also do the above in a single pass by copying the objects to keep into the current index of the original array, minus an offset for the number of removed items. Then just adjust the length at the end.
Comments
As you've found out, you can't just pass an array of numbers to a function that wants a single number. Instead, you can utilize a for loop and iterate through each of the numbers.
var itemsToRemove = [171, 182, 199, 234];
for (var i = 0; i < itemsToRemove.length; i++) {
var id = itemsToRemove[i];
if (mdl.findObjectByKey(response, 'cat_id', id) == true) {
var catId = response.map(item => item.cat_id).indexOf(item);
response.splice(catId, 1);
}
}
or using a for..of loop (and some other newer niceties):
const itemsToRemove = [171, 182, 199, 234];
for (let id of itemsToRemove) {
if (mdl.findObjectByKey(response, 'cat_id', id)) {
let catId = response.map(item => item.cat_id).indexOf(item);
response.splice(catId, 1);
}
}