JavaScript数组搜索和删除字符串?

253

我有:

var array = new Array();
array.push("A");
array.push("B");
array.push("C");

我想要像这样做:

array.remove("B");

但是没有remove函数。我该怎么做呢?


5
使用 .indexOf().splice() 的组合应该能解决问题。或者可以考虑使用 .filter() - Marc B
1
请看这里:https://dev59.com/wG865IYBdhLWcg3wKLT6 - benedict_w
可能是重复的问题:如何通过值从数组中删除项目? - totymedli
13个回答

414
我实际上正在用一个更近期的一行解决方案更新这个帖子:
let arr = ['A', 'B', 'C'];
arr = arr.filter(e => e !== 'B'); // will return ['A', 'C']

基本思想是通过选择与要删除的元素不同的所有元素来过滤数组。

换句话说,在上面的例子中:

“如果数组中的元素 e 不等于 B,则将其保留在新数组中”

注意:将删除所有出现的元素。

参见:

MDN Web Docs - Array.prototype.filter()

编辑:

如果您只想删除第一次出现的元素:

t = ['A', 'B', 'C', 'B'];
t.splice(t.indexOf('B'), 1); // will return ['B'] and t is now equal to ['A', 'C', 'B']

2
这个解决方案返回数组的副本,而使用splice则会直接删除元素。选择哪种方法取决于上下文。 - twhitehead
8
这非常适合 Redux 相关的操作,其中你需要返回一个新的状态。 - colinwong
@Regis,实际上不是这样的,arr.filter会返回一个新的数组。因此,arr.filter(e => e!== 'B') 不会修改 arr。 或者我没有正确理解你的评论? - Tyrannas
有没有一种方法可以在第一次出现时停止执行?所以如果有5个“B”,只删除一个? - Ari
1
@Ari 我已经更新了答案,以便仅删除一个元素。 - Tyrannas
显示剩余2条评论

175

倒序遍历列表,使用.splice方法。

var array = ['A', 'B', 'C']; // Test
var search_term = 'B';

for (var i=array.length-1; i>=0; i--) {
    if (array[i] === search_term) {
        array.splice(i, 1);
        // break;       //<-- Uncomment  if only the first term has to be removed
    }
}

当需要删除所有搜索词出现的情况时,反向顺序非常重要。否则计数器会增加,您将跳过元素。

当只需要删除第一个匹配项时,以下内容也可以使用:

var index = array.indexOf(search_term);    // <-- Not supported in <IE9
if (index !== -1) {
    array.splice(index, 1);
}

1
我猜是因为在反向迭代时速度稍微快一些。 - Ben Clayton
1
@BenClayton:谢谢。就 JavaScript 而言,这个并不总是正确的。倒数到 0 不会像在 C 语言中那样自动更快。当然,只要你缓存了限制,这并不会使事情变得复杂,如果你在第一次匹配后继续进行(但如果你停止在它上面,就不会有问题)。 - T.J. Crowder
如果我们追求速度,为什么不使用 while 循环呢? :D - Snuffleupagus
12
他的回答并不关乎速度,他甚至在回答中说了这一点。它关乎跳过元素。如果你在第5个位置并且切掉该位置,原来位于第6个位置的元素现在就在第5个位置。但是,循环计数器会增加,下一次迭代会到达第6个位置,这就是你跳过一个项目的地方。这就是为什么它是逆序的原因。 - amenthes
1
如果您在前向循环中删除项目,并且某个项目被删除,则最后一次迭代可能会抛出空指针异常,因为它将引用不存在的索引。 - Drenai

51

一句话列表

让我们来解决这个数组的问题:

var array = ['A', 'B', 'C'];

1. 仅删除第一个: 如果您确信该项存在,请使用

array.splice(array.indexOf('B'), 1);

2. 仅移除最后一个: 如果确定该项存在,则使用

array.splice(array.lastIndexOf('B'), 1);

3. 删除所有出现的内容:

array = array.filter(v => v !== 'B'); 

自己注意:splice() 返回一个包含 被删除 元素的数组(参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice#return_value)。 - M Imam Pratama

25

演示

你需要使用 .indexOf() 来找到你要查找的位置,然后使用 .splice() 将其删除。

function remove(arr, what) {
    var found = arr.indexOf(what);

    while (found !== -1) {
        arr.splice(found, 1);
        found = arr.indexOf(what);
    }
}

var array = new Array();
array.push("A");
array.push("B");
array.push("C");
 ​   
remove(array, 'B');
alert(array)​​​​;

这将处理所有出现的情况。


对于不支持 .indexOf() 的浏览器,你可以将 这个 添加到你的 JavaScript 文件中。 - qwertymk
是的,优雅。如果您需要删除某些元素的选项,例如仅第一个:相同更新:http://jsfiddle.net/qpZFd/9/ - sebilasse
我总是收到以下错误:Uncaught ReferenceError: array is not defined。出了什么问题? - Pathros
如果您选择这种方法,可以更充分地利用.indexOf()。如果在while-loop中将found作为第二个参数传递给.indexOf()调用,那么已经检查过并且最终不相等的数组元素将不会再次被检查:found = arr.indexOf(what, found); - pimmhogeling

18

简单来说

array.splice(array.indexOf(item), 1);

11
如果什么也没找到,indexOf会返回-1,而splice会从数组末尾删除一个元素。 - Ricky Spanish

4
const changedArray = array.filter( function(value) {
  return value !== 'B'
});

或者您可以使用:

const changedArray = array.filter( (value) => value === 'B');

changedArray将包含不包括值为“B”的元素。

3

简单的解决方案(ES6)

如果您没有重复元素

Array.prototype.remove = function(elem) {
  var indexElement = this.findIndex(el => el === elem);
  if (indexElement != -1)
    this.splice(indexElement, 1);
  return this;
};   

Online demo (fiddle)


1
如果没有找到匹配项,此解决方案始终会删除最后一个元素。 - markus s

3

如果要从字符串数组中删除另一个字符串数组:

const names = ['1','2','3','4']
const excludeNames = ['2','3']
const filteredNames = names.filter((name) => !excludeNames.includes(name));
// ['1','4']

2

使用:

array.splice(2, 1);

这将从数组中删除一个项目,从索引2(第3个项目)开始


2
实际上,它将从数组中删除第二个项目,索引从零开始。这个语句有歧义,更简单的例子可以是 array.splice(2,1),它会从数组中删除索引为 2 的 1 个项目。 请查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice获取更多详细信息。 - imdzeeshan

2

你需要自己编写remove函数。可以遍历数组,获取要删除的项的索引,并使用splice函数将其删除。

另一种方法是创建一个新数组,遍历当前数组,如果当前对象与要删除的对象不匹配,则将其放入新数组中。


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