如何从数组中删除特定项目?

javascript arrays

如何从数组中删除特定值?就像是:

array.remove(value);  // removes all elements with value

我必须使用核心 JavaScript。不允许使用框架。

array.remove(index) 或 array.pull(index) 会很有意义。 splice 非常有用,但是欢迎使用 remove() 或 pull() 方法...搜索互联网,您会发现很多“JavaScript 中 push() 的对立面是什么?”问题。如果答案可以像简单的英语一样简单,那就太好了:拉!

对于那些不想要 indexOf() + splice() 的人:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

常量数组 = [2, 5, 9];控制台.log(数组);常量索引 = array.indexOf(5); if (index > -1) { array.splice(index, 1); } // array = [2, 9] console.log(array);

array.filter((_, index) => index != number);

@Gustavo Gonçalves 我不明白这个问题:opposite of Array#push() 是众所周知的。 (当然,这不是这个问题要问的。)

3
32 revs, 27 users 13%

使用 indexOf 找到要删除的数组元素的 index,然后使用 splice 删除该索引。

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

常量数组 = [2, 5, 9];控制台.log(数组);常量索引 = array.indexOf(5); if (index > -1) { // 只有找到 item 时才拼接数组 array.splice(index, 1); // 第二个参数表示只删除一项 } // array = [2, 9] console.log(array);

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

为了完整起见,这里是函数。第一个函数只删除一个匹配项(即从 [2,5,9,1,5,8,5] 中删除 5 的第一个匹配项),而第二个函数删除所有匹配项:

函数 removeItemOnce(arr, value) { var index = arr.indexOf(value); if (index > -1) { arr.splice(index, 1); } 返回 arr; } function removeItemAll(arr, value) { var i = 0; while (i < arr.length) { if (arr[i] === value) { arr.splice(i, 1); } 其他 { ++i; } } 返回 arr; } // 用法 console.log(removeItemOnce([2,5,9,1,5,8,5], 5)) console.log(removeItemAll([2,5,9,1,5,8,5] , 5))

在 TypeScript 中,这些函数可以通过类型参数保持类型安全:

function removeItem<T>(arr: Array<T>, value: T): Array<T> { 
  const index = arr.indexOf(value);
  if (index > -1) {
    arr.splice(index, 1);
  }
  return arr;
}

严肃的问题:为什么 JavaScript 不允许在索引处删除元素的简单直观的方法?一个简单、优雅的 myArray.remove(index); 似乎是最好的解决方案,并且可以用许多其他语言实现(其中很多比 JavaScript 更早。)

@Andrew 集合和数组是两种完全不同的集合类型。

您可以通过倒数而不是倒数来简化此解决方案: for ( var i = ary.length - 1; i >= 0; i-- ) { if ( ary[i] === value ) { ary.remove(i )} }

function remove(item,array) { var new_array = [] new_array = array.filter((ar)=> ar != item) return new_array }

我参加聚会有点晚了,但这是我的两分钱:@a2br:Array.unshift() 基本上就是 pull() 如果它存在的话! @Bob:就我个人而言,我认为不存在类似于 Array.remove() 的东西是件好事。我们不希望 JavaScript 最终像 PHP 一样,是吗? xD

t
tagurit

2016 年 10 月编辑

做到简单、直观、明确(奥卡姆剃刀)

做到不可变(原始数组保持不变)

如果您的浏览器不支持标准 JavaScript 函数,请使用它们 - 使用 polyfill

在此代码示例中,我使用 array.filter(...) 函数从数组中删除不需要的项目。此函数不会更改原始数组并创建一个新数组。如果您的浏览器不支持此功能(例如 9 版之前的 Internet Explorer,或 1.5 版之前的 Firefox),请考虑 polyfilling with core-js

删除项目(ECMA-262 Edition 5 代码又名旧式 JavaScript)

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 ]

删除项目(ECMAScript 6 代码)

let value = 3

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

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

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

重要 在 Internet Explorer、45 之前的 Chrome、22 之前的 Firefox 和 10 之前的 Safari 中根本不支持 ECMAScript 6 () => {} 箭头函数语法。要在旧浏览器中使用 ECMAScript 6 语法,您可以使用 BabelJS

删除多个项目(ECMAScript 7 代码)

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

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 ]

重要 array.includes(...) 功能在 Internet Explorer、47 版之前的 Chrome、43 版之前的 Firefox、9 版之前的 Safari 和 14 版之前的 Edge 中完全不支持,但您可以polyfill with core-js

删除多个项目(将来可能)

如果 "This-Binding Syntax" 提案被接受,您将能够执行以下操作:

// 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 ]

Try it yourself in BabelJS :)

参考

Array.prototype.includes

功能组成

如果数组的内容是对象和嵌套对象怎么办

如果不满足条件,过滤器不返回空数组吗?所以你必须确保元素会在那里,否则你会在返回时将其变为空。

上述答案仅适用于原始数据类型,但对于 JavaScript,因为对象相等性并不严格

如果我只想从数组中删除一个 3 则不起作用

L
Lioness100

我不知道您期望 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 array[i] 会降低应用程序的性能并被视为不良做法

A
Andrew

这取决于您是否要保留一个空白点。

如果您确实想要一个空插槽:

array[index] = undefined;

如果您不想要一个空插槽:

//To keep the original:
//oldArray = [...array];

//This modifies the array.
array.splice(index, 1);

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

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

如果要删除数组的任一端,可以将 array.pop() 用于最后一个或 array.shift() 用于第一个(两者都返回项目的值)。

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

splice 返回另一个由已删除元素构建的数组,这有点有趣。我写了一些假设 splice 会返回新修改的列表(例如,不可变集合会做什么)。因此,在列表中只有一个项目并且该项目被删除的这种特殊情况下,返回的列表与拼接该项目后的原始列表完全相同。所以,我的应用程序进入了无限循环。

B
Ben Lesh

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

从数组中删除所有实例

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

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

S
Saša

有两种主要方法

splice(): anArray.splice(index, 1); let fruits = ['Apple', 'Banana', 'Mango', 'Orange'] 让去除 = fruits.splice(2, 1); // 水果是 ['Apple', 'Banana', 'Orange'] // 移除的是 ['Mango'] delete: delete anArray[index]; let fruits = ['Apple', 'Banana', 'Mango', 'Orange'] let removed = delete fruits(2); // fruits is ['Apple', 'Banana', undefined, 'Orange'] // 移除是 true

delete 用于数组时要小心。它适用于删除对象的属性,但不适用于数组。最好将 splice 用于数组。

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

在使用 delete 之后,您还可以预期在索引编号中存在漏洞,例如,您最终可能会得到索引 1、3、4、8、9 和 11 以及使用 delete 之前的长度。在这种情况下,所有索引的 for 循环都会崩溃,因为索引不再是连续的。

如果您由于某种原因被迫使用 delete,那么当您需要遍历数组时,您应该使用 for each 循环。事实上,如果可能,请始终避免使用索引 for 循环。这样,代码会更健壮,更不容易出现索引问题。

f
flosommerfeld

Array.prototype.removeByValue = function (val) { for (var i = 0; i < this.length; i++) { if (this[i] === val) { this.splice(i, 1);一世 - ; } } 返回这个; } var fruits = ['apple', 'banana', 'carrot', 'orange']; fruits.removeByValue('banana');控制台日志(水果); // -> ['apple', 'carrot', 'orange']

s
slosd

无需使用 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);
    }
  }
}

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

indexofmove 慢大约 10 倍。即使通过在 splice 中移除对 indexOf 的调用进行了改进,它的性能也比 move 差得多。

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
a
amd

这提供了一个谓词而不是一个值。

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

用法

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

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

定义

var helper = {
 // Remove and return the first occurrence

 remove: 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

 removeAll: 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;
 },
};

将您的代码放在代码片段中,以便其他用户可以看到结果

M
Masoud Aghaei

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

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

这会从数组中删除所有元素,并且比 sliceindexOf 的组合运行速度更快。

m
magiccrafter

约翰·雷西格 posted a good implementation

// 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 的原始实现没有这个问题。

d
darmis

您可以使用 ES6。例如,在这种情况下删除值“3”:

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

输出 :

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

这个答案很好,因为它创建了原始数组的副本,而不是直接修改原始数组。

注意:Array.prototype.filter 是 ECMAScript 5.1(没有 IE8)。如需更具体的解决方案:stackoverflow.com/a/54390552/8958729

P
Peter Mortensen

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

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

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

虽然优雅简洁,但 OP 只明确提到了核心 JS

P
Peter Mortensen

如果您想要一个删除了已删除位置的新数组,您始终可以删除特定元素并过滤掉该数组。对于未实现过滤器方法的浏览器,它可能需要扩展 array object,但从长远来看,它会更容易,因为您只需这样做:

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]

B
Bhargav Rao

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

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

如果你知道一个项目的索引

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

一种方法是使用 slice()

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

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

如果你知道价值

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

const items = ['a', 'b', 'c', 'd', 'e', 'f'] const valueToRemove = 'c' const filtersItems = items.filter(item => item !== valueToRemove)控制台.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"] 控制台。日志(过滤项目)

按价值

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

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

避免改变原始数组

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

(最初发布在我的网站 https://flaviocopes.com/how-to-remove-item-from-array/

您能否详细说明为什么应避免修改原始数组?我正在以相反的顺序迭代一个数组,并且想要删除或保留当前元素。在循环之后,我只剩下数组中保留的元素,可以直接将其用于下一个操作。您的示例将让我在每次迭代时复制数组。我还可以创建一个新数组并将所有元素推入其中,但与我原来的方法相比,这不是内存开销吗?

M
Masoud Aghaei

查看此代码。它适用于所有主流浏览器。

remove_item = function(arr, value) { var b = ''; for (b in arr) { if (arr[b] === value) { arr.splice(b, 1);休息; } } 返回 arr; }; var 数组 = [1,3,5,6,5,9,5,3,55] var res = remove_item(array,5);控制台.log(res)

@RolandIllig 除了使用 for in 循环和脚本可以更早停止的事实,直接从循环返回结果。赞成票是合理的;)

我还应该重申 yckart 的评论,即 for( i = 0; i < arr.length; i++ ) 将是一种更好的方法,因为它保留了确切的索引,而不是浏览器决定存储项目的任何顺序(使用 for in)。这样做还可以让您在需要时获取值的数组索引。

C
Chun Yang

您可以使用 lodash _.pull(变异数组)、_.pullAt(变异数组)或 _.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']

这不是 OP 要求的核心 JS,是吗?

@some-non-descript-user 你是对的。但是很多像我这样的用户来这里是为了寻找一个普遍的答案,而不仅仅是针对 OP。

M
Max Alexander Hanna

从数组中删除特定元素/字符串可以在单行中完成:

theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);

在哪里:

theArray:要从中删除特定内容的数组

stringToRemoveFromArray:要删除的字符串,1是要删除的元素个数。

注意:如果“stringToRemoveFromArray”不在数组中,这将删除数组的最后一个元素。

在删除它之前首先检查元素是否存在于数组中始终是一个好习惯。

if (theArray.indexOf("stringToRemoveFromArray") >= 0){
   theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
}

取决于您在客户端计算机上运行的是新版本还是旧版本的 Ecmascript:

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

或者

var array = ['1','2','3','4','5','6'];
var newArray = array.filter(function(item){ return item !== '3' });

其中 '3' 是要从数组中删除的值。然后数组将变为:['1','2','4','5','6']

这是尝试基于单选按钮切换更新数组时对我有用的答案。

请注意,如果 "stringToRemoveFromArray" 不在您的数组中,这将删除数组的最后一个元素。

R
Ran Turner

使用 filter 是实现此要求的一种优雅方式

常量数 = 3;让 arr = [1, 2, 3, 4]; arr = arr.filter(x => x !== num);控制台.log(arr); // [1, 2, 4]

顺便说一句,filter 将删除条件中匹配的所有匹配项(不仅仅是第一次出现),就像您在以下示例中看到的那样

常量数 = 3;让 arr = [1, 2, 3, 3, 3, 4]; arr = arr.filter(x => x !== num);控制台.log(arr); // [1, 2, 4]

如果您只想删除第一次出现,可以使用 Array.prototype.splice() 方法

常量数 = 3;让 arr = [1, 2, 3, 3, 3, 4]; arr.splice(arr.indexOf(num), 1);控制台.log(arr); // [1, 2, 3, 3, 4]

d
dipenparmar12

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

const removeByIndex = (list, index) => [ ...list.slice(0, index), ...list.slice(index + 1) ]; output = removeByIndex([33,22,11,44],1) //=> [33,11,44] console.log(output)

那为什么不直接使用 filter 呢? array.filter((_, index) => index !== removedIndex);

P
Peter Mortensen

ES10

这篇文章总结了 ECMAScript 2019 (ES10) 中从数组中删除元素的常用方法。

一、一般情况

1.1。使用 .splice() 按值删除数组元素

|就地:是 | |删除重复项:Yes(loop), No(indexOf) | |按价值/指数:按指数 |

如果您知道要从数组中删除的值,则可以使用 splice 方法。首先,您必须确定目标项目的索引。然后,您使用索引作为开始元素并仅删除一个元素。

// With a 'for' loop
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
for( let i = 0; i < arr.length; i++){
  if ( arr[i] === 5) {
    arr.splice(i, 1);
  }
} // => [1, 2, 3, 4, 6, 7, 8, 9, 0]

// With the .indexOf() method
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
const i = arr.indexOf(5);
arr.splice(i, 1); // => [1, 2, 3, 4, 6, 7, 8, 9, 0]

1.2.使用 .filter() 方法删除 Array 元素

|就地:否 | |删除重复项:是 | |按价值/指数:按价值 |

通过提供过滤功能,可以从数组中过滤出特定元素。然后为数组中的每个元素调用这样的函数。

const value = 3
let arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(item => item !== value)
console.log(arr)
// [ 1, 2, 4, 5 ]

1.3.通过扩展 Array.prototype 移除 Array 元素

|就地:是/否(取决于实施)| |删除重复项:是/否(取决于实施)| |按值/索引:按索引/按值(取决于实施)|

Array 的原型可以通过其他方法进行扩展。然后这些方法将可用于创建的数组。

注意:从 JavaScript 的标准库(如 Array)扩展对象的原型被一些人认为是一种反模式。

// In-place, removes all, by value implementation
Array.prototype.remove = function(item) {
    for (let i = 0; i < this.length; i++) {
        if (this[i] === item) {
            this.splice(i, 1);
        }
    }
}
const arr1 = [1,2,3,1];
arr1.remove(1) // arr1 equals [2,3]

// Non-stationary, removes first, by value implementation
Array.prototype.remove = function(item) {
    const arr = this.slice();
    for (let i = 0; i < this.length; i++) {
        if (arr[i] === item) {
            arr.splice(i, 1);
            return arr;
        }
    }
    return arr;
}
let arr2 = [1,2,3,1];
arr2 = arr2.remove(1) // arr2 equals [2,3,1]

1.4.使用删除运算符删除数组元素

|就地:是 | |删除重复项:否 | |按价值/指数:按指数 |

使用删除运算符不会影响长度属性。也不影响后续元素的索引。数组变得稀疏,这是一种奇特的说法,即删除的项目没有被删除但变得未定义。

const arr = [1, 2, 3, 4, 5, 6];
delete arr[4]; // Delete element with index 4
console.log( arr ); // [1, 2, 3, 4, undefined, 6]

删除运算符旨在从 JavaScript 对象中删除属性,其中数组是对象。

1.5。使用对象实用程序删除数组元素 (>= ES10)

|就地:否 | |删除重复项:是 | |按价值/指数:按价值 |

ES10 引入了 Object.fromEntries,可用于从任何类似 Array 的对象创建所需的 Array,并在此过程中过滤不需要的元素。

const object = [1,2,3,4];
const valueToRemove = 3;
const arr = Object.values(Object.fromEntries(
  Object.entries(object)
  .filter(([ key, val ]) => val !== valueToRemove)
));
console.log(arr); // [1,2,4]

2.特殊情况

2.1 如果元素位于数组的末尾,则删除它

2.1.1。更改数组长度

|就地:是 | |删除重复项:否 | |按价值/指数:不适用 |

通过将 length 属性设置为小于当前值的值,可以从数组的末尾删除 JavaScript 数组元素。任何索引大于或等于新长度的元素都将被删除。

const arr = [1, 2, 3, 4, 5, 6];
arr.length = 5; // Set length to remove element
console.log( arr ); // [1, 2, 3, 4, 5]

2.1.2.使用 .pop() 方法

|就地:是 | |删除重复项:否 | |按价值/指数:不适用 |

pop 方法删除数组的最后一个元素,返回该元素,并更新长度属性。 pop 方法修改了调用它的数组,这意味着与使用 delete 不同,最后一个元素被完全删除并减少了数组长度。

const arr = [1, 2, 3, 4, 5, 6];
arr.pop(); // returns 6
console.log( arr ); // [1, 2, 3, 4, 5]

2.2.如果元素位于数组的开头,则删除它

|就地:是 | |删除重复项:否 | |按价值/指数:不适用 |

.shift() 方法的工作方式与 pop 方法非常相似,只是它删除 JavaScript 数组的第一个元素而不是最后一个元素。当元素被移除时,剩余的元素被向下移动。

const arr = [1, 2, 3, 4];
arr.shift(); // returns 1
console.log( arr ); // [2, 3, 4]

2.3.如果元素是数组中的唯一元素,则删除元素

|就地:是 | |删除重复项:不适用 | |按价值/指数:不适用 |

最快的技术是将数组变量设置为空数组。

let arr = [1];
arr = []; //empty array

或者,可以通过将长度设置为 0 来使用 2.1.1 中的技术。

A
Ammar

表现

今天 (2019-12-09) 我在 macOS v10.13.6 (High Sierra) 上针对选定的解决方案进行性能测试。我展示了 delete (A),但我没有将它与其他方法进行比较,因为它在数组中留下了空白空间。

结论

最快的解决方案是 array.splice (C) (除了 Safari 的小数组,它有第二次)

对于大数组,array.slice+splice (H) 是 Firefox 和 Safari 最快的不可变解决方案; Array.from (B) 在 Chrome 中是最快的

可变解决方案通常比不可变解决方案快 1.5 倍至 6 倍

对于 Safari 上的小表,令人惊讶的是,可变解决方案 (C) 比不可变解决方案 (G) 慢

细节

在测试中,我以不同的方式从数组中删除中间元素。 A、C 解决方案是就地的。 B、D、E、F、G、H 解是不可变的。

具有 10 个元素的数组的结果

https://i.stack.imgur.com/foNhq.png

在 Chrome 中,array.splice (C) 是最快的就地解决方案。 array.filter (D) 是最快的不可变解。最慢的是array.slice (F)。您可以在您的机器 here 上执行测试。

具有 1.000.000 个元素的数组的结果

https://i.stack.imgur.com/7zCJt.png

在 Chrome 中,array.splice (C) 是最快的就地解决方案(delete (C) 的速度类似 - 但它在数组中留下了一个空槽(因此它不会执行“完全删除”)) . array.slice-splice (H) 是最快的不可变解。最慢的是 array.filter(D 和 E)。您可以在您的机器 here 上执行测试。

var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; var log = (letter,array) => console.log(letter, array.join `,`);函数 A(array) { var index = array.indexOf(5);删除数组[索引];日志('A',数组); } 函数 B(array) { var index = array.indexOf(5); var arr = Array.from(array); arr.splice(index, 1) log('B', arr); } 函数 C(array) { var index = array.indexOf(5); array.splice(index, 1);日志('C',数组); } function D(array) { var arr = array.filter(item => item !== 5) log('D', arr); } 函数 E(array) { var index = array.indexOf(5); var arr = array.filter((item, i) => i !== index) log('E', arr); } 函数 F(array) { var index = array.indexOf(5); var arr = array.slice(0, index).concat(array.slice(index + 1)) log('F', arr); } 函数 G(array) { var index = array.indexOf(5); var arr = [...array.slice(0, index), ...array.slice(index + 1)] log('G', arr); } 函数 H(array) { var index = array.indexOf(5); var arr = array.slice(0); arr.splice(索引,1);日志('H',arr); } A([...a]); B([...a]); C([...a]); D([...a]); E([...a]); F A]); G([...a]);哈]);此代码段仅显示性能测试中使用的代码 - 它本身不执行测试。

浏览器比较:Chrome v78.0.0、Safari v13.0.4 和 Firefox v71.0.0

https://i.stack.imgur.com/Ct9DN.png

P
Peter Mortensen

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

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

我们要删除数字 4。您可以简单地使用以下代码:

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

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

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] 呢?

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。

y
yckart

我对 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");

输出 - 正如预期的那样。 [“项目 1”,“项目 1”]

您可能有与我不同的需求,因此您可以轻松地对其进行修改以适应他们。我希望这可以帮助别人。

如果您的数组真的很长并且其中有多个元素实例,这将产生可怕的行为。数组的 indexOf 方法每次都会从头开始,所以你的成本将是 O(n^2)。

@Zag:它有一个名字:Shlemiel the Painter's Algorithm

t
tagurit

我想根据ECMAScript 6回答。假设您有一个如下所示的数组:

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]

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

A
Anik Islam Abhi

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

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

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

这就是我喜欢这样做的方式。使用箭头函数,它可以是单行的。我对性能很好奇。这取代了数组也毫无价值。任何引用旧数组的代码都不会注意到更改。

z
zykadelic

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

This gist here 将解决您的问题,并且还会删除所有出现的参数,而不仅仅是 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]
C
Community

你永远不应该改变你的数组,因为这违反了函数式编程模式。您可以使用 ECMAScript 6 方法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 文档。

E
Edric

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

var myElement = "巧克力"; var myArray = ['巧克力','poptart','poptart','poptart','巧克力','poptart','poptart','巧克力']; /* 重要代码 */ for (var i = myArray.length - 1; i >= 0; i--) { if (myArray[i] == myElement) myArray.splice(i, 1); } console.log(myArray);

Live Demo

t
tagurit

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

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

然后:

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

产量:

[1, 2, 4]

您可以使用 Babelpolyfill service 来确保这在浏览器中得到很好的支持。

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

太好了,如果我在数组中有 600k 个元素并想删除前 50k 个元素,你能想象那种慢吗?这不是解决方案,需要仅删除元素且不返回任何内容的函数。

@Seraph 为此,您可能想要使用 spliceslice

@bjfletcher 那更好,在删除过程中,只需分配 50K 元素并将它们扔到某个地方。 (使用切片 550K 元素,但没有将它们从窗口中抛出)。

我更喜欢 bjfletcher 的答案,它可以像 items= items.filter(x=>x!=3) 一样短。此外,OP 没有说明对大数据集的任何要求。