javascript - 在条件下删除数组元素

dk1*_*123 53 javascript

我想知道如何在javascript中实现一个方法,删除清除某个条件的数组的所有元素.(最好不使用jQuery)

防爆.

ar = [ 1, 2, 3, 4 ];
ar.removeIf( function(item, idx) {
    return item > 3;
});
Run Code Online (Sandbox Code Playgroud)

上面将遍历数组中的每个项目并删除所有那些return true条件(在示例中,项目> 3).

我刚刚开始使用javascript,并且想知道是否有人知道一种简短有效的方法来完成这项工作.

- 更新 -

如果条件也适用于对象属性也会很好.

防爆.

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ];
ar.removeIf( function(item, idx) {
    return item.str == "c";
});
Run Code Online (Sandbox Code Playgroud)

如果项目将被删除 item.str == "c"

- update2 -

如果索引条件也可以正常工作,那就太好了.

防爆.

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ];
ar.removeIf( function(item, idx) {
    return idx == 2;
});
Run Code Online (Sandbox Code Playgroud)

Kla*_*r_1 56

您可以使用Array过滤方法.

代码如下所示:

ar = [ 1, 2, 3, 4 ];
ar = ar.filter( function(item) {
    return !(item > 3);
});
Run Code Online (Sandbox Code Playgroud)

  • 如果将“!(item> 3)”翻译成人类语言,则将是“ item <= 3”。 (20认同)
  • 请记住,Array.filter 方法创建一个新数组。如果您在另一个变量中引用数组,则该引用将被破坏: `ar1 = [1, 2, 3, 4]; ar2 = ar1; ar1 = ar1.filter(item => !(item > 3)); 控制台.log(ar1); 控制台.log(ar2);` (9认同)
  • @Miha_x64 在 JavaScript 中, `!(item > 3)` 与 `item <= 3` 并不完全相同。如果该数组包含“未定义”项,则“!(item > 3)”将为 true,而“item <= 3”将为 false。 (9认同)
  • 这不会从数组中删除项目。这会生成一个新数组并分配给“ar”变量。如果任何其他变量引用了“ar”中的初始数组,它们不会被更新/影响。我不会考虑这个答案 (3认同)

pic*_*ypg 37

你可以添加自己的方法Array来做类似的事情,如果filter不适合你.

Array.prototype.removeIf = function(callback) {
    var i = 0;
    while (i < this.length) {
        if (callback(this[i], i)) {
            this.splice(i, 1);
        }
        else {
            ++i;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

对我而言,这是JavaScript最酷的功能之一.伊恩指出了一种更有效的方法来做同样的事情.考虑到它是JavaScript,每一点都有帮助:

Array.prototype.removeIf = function(callback) {
    var i = this.length;
    while (i--) {
        if (callback(this[i], i)) {
            this.splice(i, 1);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这样就无需担心更新length或捕捉下一个项目,因为你的工作方式是左,而不是正确.

  • 那有点乱.尝试http://jsfiddle.net/n8JEy/4/ - 你没有将'i`作为第二个参数传递给回调 (4认同)
  • 改变预定义类的原型是有风险的。应该只以polyfill-ish 的方式完成,即添加已经在规范中声明但浏览器尚未实现的成员。感谢您的解决方案,我将其用作本地函数。 (2认同)

Ble*_*der 31

你可以使用Array.filter(),反之亦然:

ar.filter(function(item, idx) {
    return item <= 3;
});
Run Code Online (Sandbox Code Playgroud)

  • Array.filter()不返回带有过滤元素的新数组吗?有什么东西只是从数组中删除元素? (14认同)
  • 在IE8或更低版本中不支持.你也应该否定原始表达式,或者它应该是`<=`. (2认同)

小智 5

您可以使用lodash.remove

var array = [1, 2, 3, 4];
var evens = _.remove(array, function(n) {
  return n % 2 == 0;
});

console.log(array);
// => [1, 3]

console.log(evens);
// => [2, 4]
Run Code Online (Sandbox Code Playgroud)


mic*_*czy 5

使其成为具有箭头功能的单线:

ar = ar.filter(i => i > 3);
Run Code Online (Sandbox Code Playgroud)


ori*_*dam 5

如果您需要仅删除一项,并且您确定该项存在,则可以使用 splice:

ar.splice(ar.findIndex(el => el.id === ID_TO_REMOVE), 1);
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/oriadam/72kgprw5/

警告当未找到项目时,上述操作将失败,因此当您因某种原因已检查该项目是否存在时,请使用它。

编辑:filter有效,但在某些情况下您可能更喜欢使用拼接。它比过滤器快约 10 倍,并就地更改数组。

例如,当您需要在删除该项目之前对其进行处理时:

let foundIdx=arr.findIndex(x=>x.id=123);
if (foundIdx>=0) {
    const found=arr[foundIdx];
    /* ...do things with found item... */
    arr.splice(foundIdx,1); 
}
Run Code Online (Sandbox Code Playgroud)