I have this code using lodash:
_.remove(this.home.modal.data.subTopics, function (currentObject) {
return currentObject.subTopicId === subTopicToDelete;
});
Can someone give me advice as to how I could do the same using modern browser functions without lodash?
Note it would be okay for the output of the remove to go into another variable.
I have this code using lodash:
_.remove(this.home.modal.data.subTopics, function (currentObject) {
return currentObject.subTopicId === subTopicToDelete;
});
Can someone give me advice as to how I could do the same using modern browser functions without lodash?
Note it would be okay for the output of the remove to go into another variable.
Share Improve this question edited Nov 4, 2014 at 14:29 Samantha J T Star asked Nov 4, 2014 at 14:20 Samantha J T StarSamantha J T Star 33k89 gold badges257 silver badges441 bronze badges 1- 1 You can see the source at github./lodash/lodash/blob/master/lodash.js#L4060-L4075 – Gabriele Petrioli Commented Nov 4, 2014 at 14:29
3 Answers
Reset to default 4You could use Array#filter()
and negate the filter clause:
this.home.modal.data.subTopics.filter(function (currentObject) {
return currentObject.subTopicId !== subTopicToDelete;
});
This will return an array where subTopicId
does not equal subTopicToDelete
. It's then up to you to save it in a variable or wherever.
Or, if you want to create a method out of it, you could do:
function remove(array, filterMethod) {
return array.filter(function(){
return !filterMethod.apply(this, arguments);
});
}
Why not have a look at lodash's source code for _.remove
?
function remove(array, predicate, thisArg) {
var index = -1,
length = array ? array.length : 0,
result = [];
predicate = getCallback(predicate, thisArg, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result.push(value);
splice.call(array, index--, 1);
length--;
}
}
return result;
}
(The getCallback
call is not really interesting here, just replace it with a predicate function that returns a boolean value for the given arguments: value, index, array. Not all of them need to be supplied obviously, this is JavaScript after all!)
Lodash uses Array.prototype.splice
at the appropriate position, pushing the removed element onto the result array. Then it decreases the current loop index and the saved length
by 1 using --
, because every time you use .splice
, you modify the array directly, for instance:
var arr = ['a', 'b'];
arr.splice(0, 1);
arr[1] // undefined
splice
in this context really just the same as Array.prototype.splice
. You can as well do array.splice(index--, 1)
.
A maybe more simple/understandable way is to (for-)loop through the array from the right, starting at array.length - 1
and ending at 0
. Then splice every element at the current index, if it passes the predicate function, and push the result value of that operation onto the result array. Return the result array after the loop.
This works the same, because if you start removing elements from the right side, the index of the rest of the looped elements doesn't change. Maybe there are performance advantages to lo-dash's code, but I couldn't tell you that.
You could adapt Array.prototype
to suit your needs. Some people don't like this approach, but it can be useful sometimes. In this example I pass in the key and the value I want to amend the array by:
if (!Array.prototype.remove) {
Array.prototype.remove = function (key, value) {
return this.filter(function (el) {
return el[key] !== value;
});
}
}
data.remove('name', 'dan');
DEMO