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

问题描述:

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

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

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

解决方案1:

huntsbot.com – 高效赚钱,自由工作

使用 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(arr: Array, value: T): Array { 
  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

解决方案2:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

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 则不起作用

解决方案3:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

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

解决方案4:

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

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

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

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 会返回新修改的列表(例如,不可变集合会做什么)。因此,在列表中只有一个项目并且该项目被删除的这种特殊情况下,返回的列表与拼接该项目后的原始列表完全相同。所以,我的应用程序进入了无限循环。

解决方案5:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

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

从数组中删除所有实例

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

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

解决方案6:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

有两种主要方法

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 循环。这样,代码会更健壮,更不容易出现索引问题。

解决方案7:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

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

解决方案8:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

无需使用 indexOf 或 splice。但是,如果您只想删除一个元素的一次出现,它的性能会更好。

查找和移动(移动):

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;
}

使用 indexOf 和 splice (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 次运行):

indexof 比 move 慢大约 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

解决方案9:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

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

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

用法

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

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

解决方案10:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

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

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 的组合运行速度更快。

解决方案11:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

约翰·雷西格 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 的原始实现没有这个问题。

原文链接:https://www.huntsbot.com/qa/6Lka/how-can-i-remove-a-specific-item-from-an-array?lang=zh_CN

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值