如何从JavaScript中删除数组中的特定元素?

Walker 6864 javascript arrays

我有一个Numbers数组,我正在使用该.push()方法向其中添加元素.

有没有一种简单的方法从数组中删除特定元素?相当于像array.remove(number);.

我必须使用核心的JavaScript - 框架是不允许的.

Tom Wadley.. 9908

找到index要删除的数组元素,然后删除该索引splice.

splice()方法通过删除现有元素和/或添加新元素来更改数组的内容.

var array = [2, 5, 9];
console.log(array)
var index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}
// array = [2, 9]
console.log(array);

第二个参数splice是要删除的元素数.请注意,splice修改数组并返回包含已删除元素的新数组.

  • 危险!如果您正在使用动态值(在数组中添加和删除动态值)并且数组中不存在值(索引变为-1),则上面的代码将删除数组的最后一个元素. (188认同)
  • @AlexandreWiechersVaz当然它保留了秩序,如果没有,那么它绝对毫无价值 (15认同)
  • @Peter,是的,你可能是对的.本文解释了更多并且针对不兼容的浏览器提供了一种解决方法:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf (10认同)
  • 您可以通过包含代码[此处给出]来克服IE浏览器支持问题(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility) (10认同)
  • @AdrianP.空数组的`array.indexOf(testValue)`将为-1,如果你正在测试那么没有拼接.也许答案已经改变了. (10认同)
  • @UpTheCreek我认为很清楚:动态填充数组意味着有时候你有一个空数组.通过使用此解决方案,您可以尝试删除不存在的最后一个元素.结果是JS错误.如果你在这个数组中有相同数量的元素,那么一切都很好.你可以使用它. (7认同)
  • @Imray` .splice`返回被删除的元素,而不是新数组.http://jsfiddle.net/bB7Ey/85/ (7认同)
  • 请注意,如果您使用非基本类型,则"Array.indexOf()"不会测试对象是否相等.它只适用于传递完全相同的对象引用.请参阅:http://jsfiddle.net/b0e7zsm3/ (6认同)
  • 不要将此方法与for循环一起使用,而是使用`while(myarry.lenth - )`.原因是"当你执行一个.splice()时,数组被重新编入索引,这意味着当一个索引被移除时你将跳过一个索引,并且你的缓存.length已经过时了." http://stackoverflow.com/a/9882349/922522 (6认同)
  • IE 7,IE8,IE9,IE10不受微软自身的支持,为什么Web开发人员应该支持那些旧的浏览器呢?只显示有关升级浏览器的通知!https://support.microsoft.com/en-us/lifecycle/search?sort=PN&alpha=internet%20explorer&Filter=FilterNO (6认同)
  • splice是否保留数组顺序? (5认同)
  • indexOf在我的Firefox版本(30.0)中保持返回-1.我最后写了一个简单的for循环来找到索引,它工作得很好...... (5认同)
  • 相关问题:如何使用jQuery(jQuery.grep).http://stackoverflow.com/questions/3596089/how-to-remove-specifc-value-from-array-using-jquery (5认同)
  • 它不起作用.看我的JSFiddle http://jsfiddle.net/bB7Ey/28/ (5认同)
  • 您可以通过在数组原型上添加`delete`函数来简化此操作的使用.我在**[a gist](https://gist.github.com/zykadelic/5069236#file-array-delete-js)**中使用了你的例子,它删除了数组中的所有目标元素,而不是只有1. (4认同)
  • 编辑我的最后一条评论为时已晚,但我只是想纠正自己.在IE 8中调用`delete`是不行的.我已经更新了gist以使用`destroy`代替. (4认同)
  • 为什么不直接使用delete方法,如`delete arname [index];`? (3认同)
  • 这在迭代数组时不是一个好方法.在我的情况下发生的事情是,它不是被删除的元素,而是它之后的元素.此外,我已经将它与jQuery的.each函数一起使用,它会导致问题,因为数组变得更小但它的长度仍然是迭代的(意味着它将尝试访问最后的空值).我无法重现最后一个错误,但第一个我可以在这个JSBin中显示它(https://jsbin.com/xufovopoji/edit?html,js,output) (2认同)
  • arr = [1,2,3,4,5] var filtered = arr.filter(function(ele){return ele!= 3;}); // filtered = [1,2,4,5]; (2认同)
  • 在不变性的时代,最好使用Array.filter()或Array.slice()[这里的例子](https://gist.github.com/iuliaL/1b4f38511fa4ddfc5e8f8491f75fc716) (2认同)

Peter Olson.. 1011

我不知道你的array.remove(int)表现如何.我可以想到你可能想要的三种可能性.

要在索引处删除数组的元素i:

array.splice(i, 1);

如果number要从数组中删除具有值的每个元素:

for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === number) {
       array.splice(i, 1);
    }
}

如果您只想使索引处的元素i不再存在,但您不希望其他元素的索引发生更改:

delete array[i];

  • `delete`不是从数组中删除元素的正确方法! (267认同)
  • `delete`不会更新数组的长度,也不会真正擦除元素,只能用特殊值`undefined`替换它. (77认同)
  • @FelixKling这取决于它是否有效,如果你想使它`array.hasOwnProperty(i)`返回`false`并让该位置的元素返回`undefined`.但我承认,这不是一件非常普遍的事情. (57认同)
  • @diosney当你说它没有真正抹去元素时,我不知道你的意思.此外,它不仅仅是简单地用'undefined'替换该索引处的值:它从数组中删除索引和值,即在`delete array [0]`之后,在array`中的`"0"将返回false . (29认同)
  • 如果你正在处理命名属性`var array = []; array ['red'] = 1; array ['green'] = 2; array ['blue'] = 3; delete array ['绿色'];` (8认同)
  • for(var i = array.length; i> = 0; i--)应为(var i = array.length-1; i> = 0; i--)因为索引从0开始(没有元素)在array [array.length]) (5认同)
  • @GrantGryczan抱歉,我不同意.我认为不需要删除它.上面的文字清楚地解释了它的作用,它帮助那些不知道什么是"删除"的人理解为什么它不能按预期工作. (5认同)
  • @GrantGryczan答案的一部分就在最底层.如果人们跳到最底层并忽略描述它的作用的描述,那不是我的错. (4认同)
  • **Splice**是在范围内操作.请记住,范围上的操作可能很昂贵(使用更多的CPU).在这个例子中,事实上它是两个for循环.如果有可能**我们应该选择更便宜的功能**. (3认同)
  • @BenG这没有意义:他们做不同的事情,怎么能受到青睐? (2认同)
  • @Paul它引用了许多地方(例如http://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/#de-referencing-misconceptions).但它的基础是底层JS引擎在垃圾收集方面比你尝试手动更快,如果你明确设置了值,你的代码将更容易理解.如果他们看到`delete array [i]`假设其余元素的索引已经更新,那么读取代码的其他人可能是一个容易犯的错误 (2认同)

Ujeenator.. 831

编辑于2016年10月

在这个代码示例中,我使用"array.filter(...)"函数从数组中删除不需要的项,此函数不会更改原始数组并创建新数组.如果您的浏览器不支持此功能(例如版本9之前的IE或版本1.5之前的Firefox),请考虑使用Mozilla中的过滤器polyfill.

删除项目(ECMA-262 Edition 5 code aka oldstyle JS)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) { 
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

删除项目(ES2015代码)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

重要事项 ES2015"()=> {}"IE中根本不支持箭头功能语法,Chrome版本为45版本,Firefox版本为22版本,Safari版本为10版本.要在旧浏览器中使用ES2015语法,您可以使用BabelJS


删除多个项目(ES2016代码)

此方法的另一个优点是您可以删除多个项目

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

重要信息 IE中根本不支持"array.includes(...)"功能,47版本之前的Chrome版本,43版本之前的Firefox版本,9版本之前的Safari版本以及14版本之前的Edge版本所以这里是来自Mozilla的polyfill

删除多个项目(尖端实验性JavaScript ES2018?)

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

在BabelJS中自己尝试:)

参考

  • 比公认的解决方案更好,因为它不假设只出现一次匹配,并且不可变性更可取 (27认同)
  • 对于大型数组,`filter`必须慢得多? (8认同)
  • 但是,有时我们想要从原始数组中删除元素(非不可变),例如Angular 2*ngFor指令中使用的数组 (4认同)
  • 使用过滤器比使用接头好得多.太简单. (4认同)
  • 这是一个很好的答案.Splice是一种用于改变不过滤的专用函数.`filter`可能性能较慢,但代码更安全,更好.此外,您可以通过在lambda中指定第二个参数来按索引进行过滤:`arr.filter((x,i)=> i!== 2)` (2认同)

xavierm02.. 383

取决于你是否想留空.

如果你想要一个空插槽,删除就可以了:

delete array[ index ];

如果不这样做,则应使用拼接方法:

array.splice( index, 1 );

如果你需要该项的值,你可以只存储返回的数组的元素:

var value = array.splice( index, 1 )[0];

如果您想按某种顺序执行此操作,可以使用array.pop()最后一个或array.shift()第一个(并且两者都返回项的值).

如果您不知道该项目的索引,您可以使用array.indexOf( item )它来获取它(在if()一个项目中获取一个项目或在一个项目中while()获取所有项目).array.indexOf( item )如果未找到,则返回索引或-1. 

  • 值得注意的是,`var value`不会存储已删除的值,而是包含已删除值的数组. (46认同)
  • `delete`不是从数组中删除元素的正确方法! (20认同)
  • 如果要"清空插槽",请使用`array [index] = undefined;`.使用`delete`会破坏优化. (13认同)
  • @Jakub非常好的评论,因为了解我失去了很多时间,并认为我的应用程序代码以某种方式被打破... (3认同)

Ben Lesh.. 251

一位朋友在Internet Explorer 8中遇到问题,并向我展示了他的所作所为.我告诉他这是错的,他告诉我他在这里得到了答案.当前的最佳答案不适用于所有浏览器(例如Internet Explorer 8),它只会删除第一次出现的项目.

从阵列中删除所有实例

function remove(arr, item) {
    for (var i = arr.length; i--;) {
        if (arr[i] === item) {
            arr.splice(i, 1);
        }
    }
}

它向后循环遍历数组(因为索引和长度将随着项目的移除而改变)并删除项目(如果已找到).它适用于所有浏览器.

  • @sroes它不应该是因为循环从`i = arr.length -1`或`i - '开始,使它与最大索引相同.`arr.length`只是`i`的初始值.`i - `将永远是**truthy**(并在每个循环op减少1),直到它等于'0'(一个假值),然后循环将停止. (8认同)

Sasa.. 142

有两种主要方法:

  1. splice():anArray.splice(index, 1);

  2. 删除:delete anArray[index];

对数组使用delete时要小心.它有利于删除对象的属性但对数组不太好.最好splice用于数组.

请记住,当您使用delete数组时,您可能会得到错误的结果anArray.length.换句话说,delete将删除元素但不会更新length属性的值.

使用删除后,您还可能会在索引号中出现漏洞,例如,您最终可能会使用删除之前的索引1,3,4,8,9,11和长度.在这种情况下,所有索引for循环都会崩溃,因为索引不再是顺序的.

如果delete由于某种原因被迫使用,那么for each在需要循环遍历数组时应该使用循环.事实上,如果可能的话,总是避免使用索引for循环.这样,代码将更加健壮,并且不易出现索引问题.


Zirak.. 118

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);

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

var rooms = ['hello', 'something']

rooms = rooms.remByVal('hello')

console.log(rooms)

  • 我不是这种方法的忠实粉丝.如果您最终使用不同的库或框架,它们最终可能会相互冲突. (13认同)
  • 不好的主意,请看这篇文章:http://stackoverflow.com/questions/948358/array-prototype-problem (10认同)
  • 如果你在数组上做一个`for in`,你就已经有了问题. (9认同)

slosd.. 87

没有必要使用indexOfsplice.但是,如果您只想删除一个元素,它会表现得更好.

查找并移动(移动):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

使用indexOfsplice(indexof):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

仅使用splice(拼接):

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

nodejs上运行时间为1000个元素的数组(平均超过10000次运行):

indexof移动慢约10倍.即使除去调用改进indexOf拼接它的性能比更糟糕的举动.

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms

  • 看起来这里提出的'move'方法应该适用于所有浏览器,并且还避免创建额外的数组; 这里的大多数其他解决方案都存在一个或两个问题.我认为这个选票应该得多,即使看起来不那么"漂亮". (3认同)

amd.. 59

太老了回复,但可能通过提供谓词而不是值来帮助某人.

注意:它将更新给定的数组,并返回受影响的行

用法

var removed = helper.removeOne(arr, row => row.id === 5 );

var removed = helper.remove(arr, row => row.name.startsWith('BMW'));

定义

var helper = {

    // Remove and return the first occurrence     

    removeOne: function(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                return array.splice(i, 1);
            }
        }
    },

    // Remove and return all occurrences  

    remove: function(array, predicate) {
        var removed = [];

        for (var i = 0; i < array.length;) {

            if (predicate(array[i])) {
                removed.push(array.splice(i, 1));
                continue;
            }

            i++;                
        }

        return removed;
    }
};


Roger.. 56

John Resig 发布了一个很好的实现:

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

如果您不想扩展全局对象,则可以执行以下操作:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

但我发布这个的主要原因是警告用户不要使用该页面评论中建议的替代实现(2007年12月14日):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

它起初似乎运行良好,但是通过一个痛苦的过程我发现它在尝试删除数组中倒数第二个元素时失败了.例如,如果您有一个10个元素的数组,并尝试使用以下方法删除第9个元素:

myArray.remove(8);

你最终得到一个8元素阵列.不知道为什么,但我确认John的原始实现没有这个问题.


vatsal.. 54

Underscore.js可用于解决多个浏览器的问题.它使用内置浏览器方法(如果存在).如果它们不存在,就像旧的Internet Explorer版本一样,它使用自己的自定义方法.

从数组中删除元素的简单示例(来自网站):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]


Salvador Dal.. 53

您可以使用过滤方法轻松完成:

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log( remove([1, 2, 1, 0, 3, 1, 4], 1) );

这将从数组中删除所有元素,并且比slice和indexOf的组合更快地工作

  • 另请注意,Array.prototype.filter是ECMAScript 5.1(无IE8) (3认同)

Loupax.. 42

如果要删除删除位置的新数组,可以始终删除特定元素并过滤掉数组.对于没有实现过滤方法的浏览器,可能需要对数组对象进行扩展,但从长远来看,它更容易,因为您所做的只是:

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

应该显示 [1, 2, 3, 4, 6]


rajat44.. 38

您可以使用ES6.

var array=['1','2','3','4','5','6']
var index = array.filter((value)=>value!='3');

输出:

["1", "2", "4", "5", "6"]

  • 这个答案很好,因为它创建了原始数组的副本,而不是直接修改原始数组. (2认同)

Ekramul Hoqu.. 35

看看这段代码.它适用于所有主流浏览器.

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

调用此功能

remove_item(array,value);

  • @RolandIllig除了使用`for in`循环以及脚本可以提前停止的事实,直接从循环返回结果.赞成票是合理的;) (4认同)

Chun Yang.. 34

你可以使用lodash _.pull(mutate array),_.pullAt(mutate array)或_.without(不要改变数组),

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']

  • @ some-non-descript-user你是对的.但是很多像我一样的用户来这里寻找一个不仅仅是OP的一般答案. (10认同)

Alireza.. 32

好的,例如你有以下数组:

var num = [1, 2, 3, 4, 5];

我们想删除4号,你可以简单地做下面的代码:

num.splice(num.indexOf(4), 1); //num will be [1, 2, 3, 5];

如果重用此函数,则编写一个可重用的函数,该函数将附加到Native数组函数,如下所示:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1) return;
  this.splice(i, 1); //num.remove(5) === [1, 2, 3];
}

但是,如果您使用下面的数组而不是数组中的[5] s,那该怎么办?

var num = [5, 6, 5, 4, 5, 1, 5];

我们需要一个循环来检查所有这些,但更简单,更有效的方法是使用内置的JavaScript函数,所以我们编写一个使用如下所示的过滤器的函数:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) //return [1, 2, 3, 4, 6]

还有第三方库可以帮助你做这些,比如Lodash或者Underscore,更多信息请看lodash _.pull,_.pullAt或_.without.


大智慧.. 27

我是JavaScript的新手,需要这个功能.我只写了这个:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

然后,当我想使用它时:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

输出 - 正如所料.["item1","item1"]

您可能有不同的需求,因此您可以轻松修改它以适应它们.我希望这可以帮助别人.


Abdennour TO.. 24

ES6和无突变:( 2016年10月)

const removeByIndex = (list, index) =>
  [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];

然后 :

removeByIndex([33,22,11,44],1) //=> [33,11,44]


zykadelic.. 22

更新:仅当您不能使用ECMAScript 2015(以前称为ES6)时,才建议使用此方法.如果你可以使用它,这里的其他答案提供了更简洁的实现.


这里的要点将解决您的问题,并删除所有出现的参数而不只是1(或指定的值).

Array.prototype.destroy = function(obj){
    // Return null if no objects were found and removed
    var destroyed = null;

    for(var i = 0; i < this.length; i++){

        // Use while-loop to find adjacent equal objects
        while(this[i] === obj){

            // Remove this[i] and store it within destroyed
            destroyed = this.splice(i, 1)[0];
        }
    }

    return destroyed;
}

用法:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]


flurdy.. 21

如果阵列中有复杂对象,可以使用过滤器吗?在$ .inArray或array.splice不那么容易使用的情况下.特别是如果对象在数组中可能很浅.

例如,如果您有一个带有Id字段的对象,并且您希望从数组中删除该对象:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});


Flavio Copes.. 20

以下是使用JavaScript从数组中删除项的几种方法.

所描述的所有方法都不会改变原始数组,而是创建一个新数组.

如果您知道项目的索引

假设您有一个数组,并且想要移除一个位置的项目i.

一种方法是使用slice():

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i-1).concat(items.slice(i, items.length))

console.log(filteredItems)

slice()使用它接收的索引创建一个新数组.我们只是创建一个新数组,从开始到我们想要删除的索引,并从我们删除的第一个位置到数组末尾的第一个位置连接另一个数组.

如果你知道价值

在这种情况下,一个很好的选择是使用filter(),它提供了更具说明性的方法:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)

console.log(filteredItems)

这使用ES6箭头功能.您可以使用传统功能来支持旧版浏览器:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})

console.log(filteredItems)

或者您可以使用Babel并将ES6代码转发回ES5,使其更易于浏览旧浏览器,同时在代码中编写现代JavaScript.

删除多个项目

如果不是单个项目,您想要删除多个项目,该怎么办?

让我们找到最简单的解决方案.

按索引

您只需创建一个函数并删除系列中的项目:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]

console.log(filteredItems)

按价值

您可以在回调函数中搜索包含:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

console.log(filteredItems)

避免改变原始数组

splice()(不要混淆slice())改变原始数组,应该避免.

(最初发布于https://flaviocopes.com/how-to-remove-item-from-array/)


Adeel Imran.. 19

你永远不应该在你的数组中改变你的数组.因为这是针对功能编程模式的.你可以做的是创建一个新的数组,而不引用你想要使用es6方法更改数据的数组filter;

var myArray = [1,2,3,4,5,6];

假设你想要5从数组中删除,你可以这样做.

myArray = myArray.filter(value => value !== 5);

这将为您提供一个没有您想要删除的值的新数组.结果将是

 [1,2,3,4,6]; // 5 has been removed from this array

为了进一步理解,您可以阅读Array.filter上的MDN文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter


bjfletcher.. 18

一个更现代的ECMAScript 2015(以前称为Harmony或ES 6)方法.鉴于:

const items = [1, 2, 3, 4];
const index = 2;

然后:

items.filter((x, i) => i !== index);

产量:

[1, 2, 4]

您可以使用Babelpolyfill服务来确保跨浏览器能够很好地支持它.

  • 请注意,`.filter`返回一个新数组,这与从同一数组中删除元素不完全相同.这种方法的好处是可以将数组方法链接在一起.例如:`[1,2,3] .filter(n => n%2).map(n => n*n)=== [1,9] (4认同)

wharding28.. 16

我知道已有很多答案,但其中许多似乎使问题复杂化.这是一种删除键的所有实例的简单递归方法 - 调用self直到找不到索引.是的,它仅适用于浏览器indexOf,但它很简单,可以轻松填充.

独立功能

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

原型方法

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}


Jeff Noel.. 15

如果元素有多个实例,则可以执行向后循环以确保不会搞砸索引.

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

现场演示


Ardi.. 15

基于所有主要正确的答案并考虑到建议的最佳实践(特别是不直接使用Array.prototype),我想出了以下代码:

function arrayWithout(arr, values) {
  var isArray = function(canBeArray) {
    if (Array.isArray) {
      return Array.isArray(canBeArray);
    }
    return Object.prototype.toString.call(canBeArray) === '[object Array]';
  };

  var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
  var arrCopy = arr.slice(0);

  for (var i = arrCopy.length - 1; i >= 0; i--) {
    if (excludedValues.indexOf(arrCopy[i]) > -1) {
      arrCopy.splice(i, 1);
    }
  }

  return arrCopy;
}

回顾上述功能,尽管它工作正常,但我意识到可能会有一些性能提升.使用ES6而不是ES5也是一种更好的方法.为此,这是改进的代码:

const arrayWithoutFastest = (() => {
  const isArray = canBeArray => ('isArray' in Array) 
    ? Array.isArray(canBeArray) 
    : Object.prototype.toString.call(canBeArray) === '[object Array]';

  let mapIncludes = (map, key) => map.has(key);
  let objectIncludes = (obj, key) => key in obj;
  let includes;

  function arrayWithoutFastest(arr, ...thisArgs) {
    let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;

    if (typeof Map !== 'undefined') {
      withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
      includes = mapIncludes;
    } else {
      withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {}); 
      includes = objectIncludes;
    }

    const arrCopy = [];
    const length = arr.length;

    for (let i = 0; i < length; i++) {
      // If value is not in exclude list
      if (!includes(withoutValues, arr[i])) {
        arrCopy.push(arr[i]);
      }
    }

    return arrCopy;
  }

  return arrayWithoutFastest;  
})();

如何使用:

const arr = [1,2,3,4,5,"name", false];

arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)

我目前正在撰写一篇博文,其中我对Array的几个解决方案进行了基准测试,没有出现问题,并比较了运行所需的时间.完成该帖后,我将使用链接更新此答案.只是为了让你知道,我已经将上面的内容与lodash的内容进行了比较,如果浏览器不支持Map,它就会超过lodash!请注意,我没有使用Array.prototype.indexOfArray.prototype.includes包含exlcudeValues MapObject更快地查询!


Aram Grigory.. 15

我有另一个很好的解决方案从数组中删除:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter


Thilina Samp.. 14

你有1到9个数组,你想删除5使用下面的代码.

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);


如果你想要多个值ex: - 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 5 removed", newNumberArray);


如果要删除数组ex中的数组值: - [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

包含支持的浏览器是链接


大智慧.. 13

  Array.prototype.removeItem = function(a) {
            for (i = 0; i < this.length; i++) {
                if (this[i] == a) {
                    for (i2 = i; i2 < this.length - 1; i2++) {
                        this[i2] = this[i2 + 1];
                    }
                    this.length = this.length - 1
                    return;
                }
            }
        }

    var recentMovies = ['Iron Man', 'Batman', 'Superman', 'Spiderman'];
    recentMovies.removeItem('Superman');


nsantana.. 13

按索引删除

返回没有索引元素的数组副本的函数.

/**
* removeByIndex
* @param {Array} array
* @param {Number} index
*/
function removeByIndex(array, index){
    return array.filter(function(elem, _index){
        return index != _index;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByIndex(l, 1));

$> [ 1, 4, 5, 6, 7 ]

按值删除

返回没有Value的数组副本的函数.

/**
* removeByValue
* @param {Array} array
* @param {Number} value
*/
function removeByValue(array, value){
    return array.filter(function(elem, _index){
        return value != elem;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByValue(l, 5));

$> [ 1, 3, 4, 6, 7]


Enrico.. 11

创建新数组:

var my_array = new Array();

向此数组添加元素:

my_array.push("element1");

函数indexOf(返回索引或未找到时为-1):

var indexOf = function(needle) 
{
    if(typeof Array.prototype.indexOf === 'function') // newer browsers
    {
        indexOf = Array.prototype.indexOf;
    } 
    else // older browsers
    {
        indexOf = function(needle) 
        {
            var index = -1;

            for(var i = 0; i < this.length; i++) 
            {
                if(this[i] === needle) 
                {
                    index = i;
                    break;
                }
            }
            return index;
        };
    }

    return indexOf.call(this, needle);
};

检查此元素的索引(使用firefox和IE8 +测试):

var index = indexOf.call(my_array, "element1");

从数组中删除位于索引处的1个元素

my_array.splice(index, 1);


大智慧.. 11

我想回答一下ES6.假设你有一个如下数组:

let arr = [1,2,3,4];

如果你想删除特殊索引2,请写下面的代码:

arr.splice(2, 1); //=> arr became [1,2,4]

但是,如果你想删除一个特殊的项目3,你不知道它的索引如下所示:

arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]

提示:请使用箭头函数进行过滤回调,除非您得到一个空数组.


NullPointer.. 10

我还遇到了必须从中删除元素的情况Array..indexOf没有工作,IE*所以分享我的工作jQuery.inArray()解决方案.

var index = jQuery.inArray(val,arr);
if (index > -1) {
    arr.splice(index, 1);
    //console.log(arr);
}


Redu.. 9

我认为很多JavaScript指令都没有经过深思熟虑的函数式编程.Splice返回已删除的元素,大多数时候您需要减少的数组.这是不好的.

想象一下,你正在做一个递归调用,并且必须传递一个少一项的数组,可能没有当前的索引项.或者想象你正在进行另一个递归调用,并且必须传递一个带有元素的数组.

在这些情况下你都不能做myRecursiveFunction(myArr.push(c))myRecursiveFunction(myArr.splice(i,1)).第一个白痴实际上将传递数组的长度,第二个白痴将传递已删除的元素作为参数.

所以我实际上做了...为了删除一个数组元素并将结果作为参数传递给一个函数同时我做如下

myRecursiveFunction(myArr.slice(0,i).concat(a.slice(i+1)))

当谈到推动那更傻......我喜欢,

myRecursiveFunction((myArr.push(c),myArr))

我相信一个正确的函数式语言,一个方法变异它所调用的对象必须返回对该对象的引用作为结果.


Aidan Hoolac.. 9

2017年5月8日

大多数给定的答案适用于严格比较,这意味着两个对象都引用内存中的完全相同的对象(或者是基本类型),但通常要从具有特定值的数组中删除非基本对象.例如,如果您调用服务器并希望针对本地对象检查检索到的对象.

const a = {'field': 2} // Non-primitive object
const b = {'field': 2} // Non-primitive object with same value
const c = a            // Non-primitive object that reference the same object as "a"

assert(a !== b) // Don't reference the same item, but have same value
assert(a === c) // Do reference the same item, and have same value (naturally)

//Note: there are many alternative implementations for valuesAreEqual
function valuesAreEqual (x, y) {
   return  JSON.stringify(x) === JSON.stringify(y)
}


//filter will delete false values
//Thus, we want to return "false" if the item
// we want to delete is equal to the item in the array
function removeFromArray(arr, toDelete){
    return arr.filter(target => {return !valuesAreEqual(toDelete, target)})
}

const exampleArray = [a, b, b, c, a, {'field': 2}, {'field': 90}];
const resultArray = removeFromArray(exampleArray, a);

//resultArray = [{'field':90}]

valuesAreEqual有替代/更快的实现,但这可以完成工作.如果要检查特定字段(例如,某些检索到的UUID与本地UUID),您还可以使用自定义比较器.

另请注意,这是一个功能操作,这意味着它不会改变原始数组.


Nigel Sherid.. 8

CoffeeScript中:

my_array.splice(idx, 1) for ele, idx in my_array when ele is this_value


大智慧.. 7

使用jQuery的InArray:

A = [1, 2, 3, 4, 5, 6];
A.splice($.inArray(3, A), 1);
//It will return A=[1, 2, 4, 5, 6]`   

注意:如果找不到元素,inArray将返回-1.

  • 但OP说:"好的'老式的JavaScript - 没有框架允许" (5认同)

yckart.. 6

您可以迭代每个array-item,splice如果它存在于您的中array.

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


mboeckle.. 6

我喜欢这个版本的splice,使用$.inArray以下值删除元素:

$(document).ready(function(){
    var arr = ["C#","Ruby","PHP","C","C++"];
    var itemtoRemove = "PHP";
    arr.splice($.inArray(itemtoRemove, arr),1);
});

  • 这是jQuery,而不是核心JavaScript. (3认同)

Lars Gyrup B.. 6

Vanilla JavaScript(ES5.1) - 就地

浏览器支持:Internet Explorer 9或更高版本(详细的浏览器支持)

/**
 * Removes all occurences of the item from the array.
 *
 * Modifies the array “in place”, i.e. the array passed as an argument
 * is modified as opposed to creating a new array. Also returns the modified
 * array for your convenience.
 */
function removeInPlace(array, item) {
    var foundIndex, fromIndex;

    // Look for the item (the item can have multiple indices)
    fromIndex = array.length - 1;
    foundIndex = array.lastIndexOf(item, fromIndex);

    while (foundIndex !== -1) {
        // Remove the item (in place)
        array.splice(foundIndex, 1);

        // Bookkeeping
        fromIndex = foundIndex - 1;
        foundIndex = array.lastIndexOf(item, fromIndex);
    }

    // Return the modified array
    return array;
}

Vanilla JavaScript(ES5.1) - 不可变版本

浏览器支持:与地方版中的vanilla JavaScript相同

/**
 * Removes all occurences of the item from the array.
 *
 * Returns a new array with all the items of the original array except
 * the specified item.
 */
function remove(array, item) {
    var arrayCopy;

    arrayCopy = array.slice();

    return removeInPlace(arrayCopy, item);
}

香草ES6 - 不可变

浏览器支持:Chrome 46,Edge 12,Firefox 16,Opera 37,Safari 8(详细的浏览器支持)

/**
 * Removes all occurences of the item from the array.
 *
 * Returns a new array with all the items of the original array except
 * the specified item.
 */
function remove(array, item) {
    // Copy the array
    array = [...array];

    // Look for the item (the item can have multiple indices)
    let fromIndex = array.length - 1;
    let foundIndex = array.lastIndexOf(item, fromIndex);

    while (foundIndex !== -1) {
        // Remove the item by generating a new array without it
        array = [
            ...array.slice(0, foundIndex),
            ...array.slice(foundIndex + 1),
        ];

        // Bookkeeping
        fromIndex = foundIndex - 1;
        foundIndex = array.lastIndexOf(item, fromIndex)
    }

    // Return the new array
    return array;
}


alejandro.. 6

删除索引i处的元素,而不改变原始数组:

/**
* removeElement
* @param {Array} array
* @param {Number} index
*/
function removeElement(array, index) {
   return Array.from(array).splice(index, 1);
}

// Another way is
function removeElement(array, index) {
   return array.slice(0).splice(index, 1);
}


Kamuran Söne.. 5

通过我的解决方案,您可以使用纯JavaScript删除数组中的一个或多个项目.不需要另一个JavaScript库.

var myArray = [1,2,3,4,5]; // First array

var removeItem = function(array,value) {  // My clear function
    if(Array.isArray(value)) {  // For multi remove
        for(var i = array.length - 1; i >= 0; i--) {
            for(var j = value.length - 1; j >= 0; j--) {
                if(array[i] === value[j]) {
                    array.splice(i, 1);
                };
            }
        }
    }
    else { // For single remove
        for(var i = array.length - 1; i >= 0; i--) {
            if(array[i] === value) {
                array.splice(i, 1);
            }
        }
    }
}

removeItem(myArray,[1,4]); // myArray will be [2,3,5]


Shawn Deprey.. 5

我对基础JavaScript数组做了一个相当有效的扩展:

Array.prototype.drop = function(k) {
  var valueIndex = this.indexOf(k);
  while(valueIndex > -1) {
    this.removeAt(valueIndex);
    valueIndex = this.indexOf(k);
  }
};

  • 我读到你不应该修改你不拥有的对象 (3认同)

Victor.. 5

我刚刚在Array.prototypevia 上创建了一个polyfill Object.defineProperty来删除数组中的所需元素,而不会在稍后通过迭代时导致错误for .. in ..

if (!Array.prototype.remove) {
  // Object.definedProperty is used here to avoid problems when iterating with "for .. in .." in Arrays
  // /sf/ask/17360801/
  Object.defineProperty(Array.prototype, 'remove', {
    value: function () {
      if (this == null) {
        throw new TypeError('Array.prototype.remove called on null or undefined')
      }

      for (var i = 0; i < arguments.length; i++) {
        if (typeof arguments[i] === 'object') {
          if (Object.keys(arguments[i]).length > 1) {
            throw new Error('This method does not support more than one key:value pair per object on the arguments')
          }
          var keyToCompare = Object.keys(arguments[i])[0]

          for (var j = 0; j < this.length; j++) {
            if (this[j][keyToCompare] === arguments[i][keyToCompare]) {
              this.splice(j, 1)
              break
            }
          }
        } else {
          var index = this.indexOf(arguments[i])
          if (index !== -1) {
            this.splice(index, 1)
          }
        }
      }
      return this
    }
  })
} else {
  var errorMessage = 'DANGER ALERT! Array.prototype.remove has already been defined on this browser. '
  errorMessage += 'This may lead to unwanted results when remove() is executed.'
  console.log(errorMessage)
}

删除整数值

var a = [1, 2, 3]
a.remove(2)
a // Output => [1, 3]

删除字符串值

var a = ['a', 'ab', 'abc']
a.remove('abc')
a // Output => ['a', 'ab']

删除布尔值

var a = [true, false, true]
a.remove(false)
a // Output => [true, true]

也可以通过此Array.prototype.remove方法删除数组内的对象.你只需要指定key => value了的Object要删除.

删除对象值

var a = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 3, b: 2}]
a.remove({a: 1})
a // Output => [{a: 2, b: 2}, {a: 3, b: 2}]


归档时间:

查看次数:

5538249 次

最近记录:

9 月,2 周 前