简体   繁体   English

如何在现代浏览器中实现lodash _.remove函数?

[英]How can I implement the lodash _.remove function in modern browsers?

I have this code using lodash: 我有使用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? 有人可以给我一些建议,我如何在不使用lodash的情况下使用现代浏览器功能进行同样的操作?

Note it would be okay for the output of the remove to go into another variable. 请注意,remove的输出可以进入另一个变量。

You could use Array#filter() and negate the filter clause: 您可以使用Array#filter()并否定filter子句:

this.home.modal.data.subTopics.filter(function (currentObject) {
    return currentObject.subTopicId !== subTopicToDelete;
});

This will return an array where subTopicId does not equal subTopicToDelete . 这将返回一个数组,其中subTopicId不等于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 ? 为什么不看看lodash的源代码_.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!) getCallback调用在这里并不是很有趣,只需将其替换为谓词函数即可,该谓词函数返回给定参数的布尔值:值,索引,数组。显然不需要全部提供,毕竟这是JavaScript!)

Lodash uses Array.prototype.splice at the appropriate position, pushing the removed element onto the result array. Lodash在适当的位置使用Array.prototype.splice ,将删除的元素推到结果数组上。 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: 然后,使用--将当前循环索引和保存的length减少1,因为每次使用.splice ,都直接修改数组,例如:

var arr = ['a', 'b'];
arr.splice(0, 1);
arr[1] // undefined

splice in this context really just the same as Array.prototype.splice . 在这种情况下, splice实际上与Array.prototype.splice相同。 You can as well do array.splice(index--, 1) . 您也可以执行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 . 一种可能更简单/可以理解的方法是从右侧(for-)循环遍历数组,从array.length - 10结束。 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. lo-dash的代码也许在性能上有优势,但我无法告诉您。

You could adapt Array.prototype to suit your needs. 您可以调整Array.prototype以适合您的需求。 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 DEMO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM