通过值删除数组元素的最佳方法

57

我有一个像这样的数组

arr = ["orange","red","black","white"]

我想增强数组对象,定义一个名为deleteElem()的方法,其作用如下:

arr2 = arr.deleteElem("red"); // ["orange","black","white"] (with no hole)

如何仅使用value参数(不使用索引)来完成此任务?


这让我想起了在mootools和jquery中都有的.filter()。例如,Mootools还有.erase(),它可以像你要求的那样工作。没有必要重新发明轮子。 - Oliver
使用jQuery删除数组元素https://dev59.com/CXA65IYBdhLWcg3w2imp - itsazzad
可能是通过值从数组中删除项目的重复内容。 - Gajus
可能是如何在JavaScript中从数组中删除特定元素?的重复问题。 - Heretic Monkey
10个回答

105

下面是实现方法:

var arr = ["orange","red","black","white"];
var index = arr.indexOf("red");
if (index >= 0) {
  arr.splice( index, 1 );
}

这段代码将从你的数组中删除一个"red"的出现。


6
此外,您需要扩充数组以支持.indexOf(),但在一些旧版本的IE中不被支持。 - jfriend00
15
非常危险,因为如果“红色”不在数组中,它会删除“白色”。 - IvanM
2
@IvanMalyshev同意,这非常危险。Array.prototype.splice(index,howMany)允许负索引,因此您需要在调用splice之前检查indexOf是否未返回-1(未找到)。 - Dakota
这怎么可能是被批准的答案呢?正如@IvanMalyshev和@Dakota的评论所述,它显然是错误的。我已经给它点了踩,如果有适当的更正,我会点赞的。 - enigment
1
答案已经修复,得到了赞同,并提到了与.indexOf()兼容性的注意事项。 - enigment
这对我并不总是有效,例如(在node repl中测试):> [1].indexOf(1); 0 > [1].splice(0, 1); [ 1 ] - achalk

54

当我刚开始学习编码时,我几乎无法理解splice在做什么,即使今天它看起来也不太易读。

但可读性很重要。

我宁愿使用过滤方法,就像这样:

arr = ["orange","red","black","white","red"]

arr = arr.filter(val => val !== "red");

console.log(arr) // ["orange","black","white"]

注意所有包含“red”的元素都已从数组中删除。

从那里开始,您可以轻松处理更复杂的数据,例如对象数组。

arr = arr.filter(obj => obj.prop !== "red");

2
看起来它得到了很好的支持:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Browser_compatibility - ryannjohnson

4

1
这个解决方案移除了所有提到的数值,我只想要移除其中一个出现的数值并保留重复项,所以在我的情况下,这不是一个好的解决方案。 例如: arr = ["orange", "red", "black", "white", "orange"]; arr = _.without(arr, "orange"); => arr = ["red", "black", "white"] 我想保留最后一个 "orange"。 是否有一种方法可以使用 underscore.js 或 lodash.js 来实现呢? - Vali D

3
技巧在于从数组末尾开始遍历,这样在删除元素时就不会弄乱索引。
var deleteMe = function( arr, me ){
   var i = arr.length;
   while( i-- ) if(arr[i] === me ) arr.splice(i,1);
}

var arr = ["orange","red","black", "orange", "white" , "orange" ];

deleteMe( arr , "orange");

现在 arr 的值是 ["red", "black", "white"]。


1

我的方法是,让我们看看别人怎么说。它还支持一个“equals”方法。

 // Remove array value
 // @param {Object} val
 Array.prototype.removeByValue = function (val) {
    for (var i = 0; i < this.length; i++) {
       var c = this[i];
       if (c == val || (val.equals && val.equals(c))) {
          this.splice(i, 1);
          break;
       }
    }
 };

阅读https://dev59.com/inA75IYBdhLWcg3w8-LZ#3010848,了解在使用原型与数组时迭代的影响。


坏主意,参见此帖子:https://dev59.com/mHNA5IYBdhLWcg3wdtv5 - MMeah
不是的,但我明白你的意思:请阅读https://dev59.com/inA75IYBdhLWcg3w8-LZ#3010848并使用推荐的数组迭代方法。我会在上面添加一条注释。这个主题不仅适用于上面的函数,而且适用于所有数组/原型场景。 - Horst Walter

1
Array.prototype.deleteElem = function(val) {
    var index = this.indexOf(val); 
    if (index >= 0) this.splice(index, 1);
    return this;
}; 
var arr = ["orange","red","black","white"];
var arr2 = arr.deleteElem("red");

1
或者简单地检查所有项目,创建一个新的数组,并返回非相等的内容。
var arr = ['orange', 'red', 'black', 'white'];

console.info('before: ' + JSON.stringify(arr));

var deleteElem = function ( val ) {
    var new_arr = [];
    for ( var i = 0; i < this.length; i++ ) {
        if ( this[i] !== val ) {
            new_arr.push(this[i]);
        }
    }
    return new_arr;
};

arr = deleteElem('red');

console.info('after: ' + JSON.stringify(arr));

http://jsfiddle.net/jthavn3m/


0

最好的方法是使用splice并重建新数组,因为splice后,数组的长度不会改变。

请查看我的答案:

function remove_array_value(array, value) {
    var index = array.indexOf(value);
    if (index >= 0) {
        array.splice(index, 1);
        reindex_array(array);
    }
}
function reindex_array(array) {
   var result = [];
    for (var key in array) {
        result.push(array[key]);
    }
    return result;
}

例子:

var example_arr = ['apple', 'banana', 'lemon'];   // length = 3
remove_array_value(example_arr, 'banana');

香蕉已被删除,数组长度为2


0
如果改变数组中元素的位置不是问题,你可以这样解决:

var arr = ["orange","red","black","white"];
arr.remove = function ( item ) {
  delete arr[item];
  arr.sort();
  arr.pop();
  console.log(arr);
}

arr.remove('red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


-2

给你:

arr.deleteElem = function ( val ) {
    for ( var i = 0; i < this.length; i++ ) {
        if ( this[i] === val ) {
            this.splice( i, 1 );
            return i;
        }
    }
};

演示实例: http://jsfiddle.net/4vaE2/3/

deleteElem 方法返回被移除元素的索引。

var idx = arr.deleteElem( 'red' ); // idx is 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接