Удалить элемент из массива в JavaScript

В JavaScript и, как и во многих других языках, в какой-то момент вам, вероятно, потребуется удалить элемент из массива. В зависимости от вашего варианта использования это может быть так же просто, как использование встроенных команд shift () или pop (), но это работает только в том случае, если элемент находится в начале или в конце массива соответственно. Многие варианты использования потребуют от вас поддержки удаления элемента из произвольного места в массиве, о чем мы здесь и поговорим. Я также объясню, как этого добиться

В JavaScript и, как и во многих других языках, в какой-то момент вам, вероятно, потребуется удалить элемент из массива. В зависимости от вашего варианта использования это может быть так же просто, как использование встроенных shift() или pop() , но это работает только в том случае, если элемент находится в начале или в конце массива соответственно. Многие варианты использования потребуют от вас поддержки удаления элемента из произвольного места в массиве, о чем мы здесь и поговорим.

Я также объясню, как добиться этого другими способами, например, с использованием служебных библиотек, которые будут обрабатывать это за вас, или если вам нужно поддерживать старые браузеры, такие как IE 8.

Ванильный JavaScript

Чтобы удалить определенный элемент из массива в JavaScript, нам нужно сначала найти местоположение элемента, а затем удалить его.

Найти местоположение по значению можно с помощью indexOf() , который возвращает индекс для первого вхождения данного значения или -1, если его нет в массиве.

Затем, используя это значение индекса, мы захотим фактически удалить элемент, что мы можем сделать с помощью метода splice()

 function removeElement(array, elem) { 
 var index = array.indexOf(elem); 
 if (index > -1) { 
 array.splice(index, 1); 
 } 
 } 

Итак, если indexOf и splice - единственные два метода, которые нам нужны для достижения этого, тогда для чего нужен if-оператор? Проверяя, больше ли индекс -1, мы проверяем, действительно ли элемент присутствует в массиве. Если это не так, а index равен -1, то использование этого значения в splice фактически удалит последний элемент в массиве, а это не то, что мы хотим.

Имейте в виду, что это удаляет только первое вхождение данного элемента. См. Следующий пример, чтобы проиллюстрировать это:

 var arr = [1, 2, 3, 3, 4, 5]; 
 removeElement(arr, 3); 
 console.log(arr); 
 
 // Output: 
 // [ 1, 2, 3, 4, 5 ] 

Обратите внимание, что вторая «3» все еще присутствует.

Если мы хотим удалить каждый экземпляр указанного элемента, мы можем добиться этого с помощью цикла while вместо оператора if:

 function removeAllElements(array, elem) { 
 var index = array.indexOf(elem); 
 while (index > -1) { 
 array.splice(index, 1); 
 index = array.indexOf(elem); 
 } 
 } 

Теперь, запустив тот же пример кода, что и выше, мы получим следующее:

 var arr = [1, 2, 3, 3, 4, 5]; 
 removeAllElements(arr, 3); 
 console.log(arr); 
 
 // Output: 
 // [ 1, 2, 4, 5 ] 

Как видите, оба элемента «3» теперь удалены из массива.

Библиотеки

Поскольку это такой распространенный вариант использования, большинство (если не все) служебных библиотек имеют функцию для удаления элементов из массива.

Лодаш

Чтобы удалить элемент, в Lodash есть метод remove() . Если у вас довольно простой вариант использования, вы просто хотите удалить примитивный элемент (например, число), то эта функция, вероятно, для вас излишняя, поскольку вам нужно передать функцию, которая определяет, соответствует ли элемент вашим критериям.

Итак, например, вот как вы удалите цифру 3:

 var arr = [1, 2, 3, 3, 4, 5]; 
 _.remove(arr, function(e) { 
 return e === 3; 
 }); 
 console.log(arr); 
 
 // Output: 
 // [ 1, 2, 4, 5 ] 

Обратите внимание, что он удалил все экземпляры 3, что является поведением по умолчанию.

Однако этот метод более полезен при удалении более сложных элементов, например объектов. Например, вы хотите удалить все объекты "люди" из массива, если им меньше 21 года:

 var people = [ 
 {name: 'Billy', age: 22}, 
 {name: 'Sally', age: 19}, 
 {name: 'Timmy', age: 29}, 
 {name: 'Tammy', age: 15} 
 ]; 
 _.remove(people, function(e) { 
 return e.age < 21 
 }); 
 console.log(people); 
 
 // Output 
 // [ { name: 'Billy', age: 22 }, { name: 'Timmy', age: 29 } ] 

Он работает примерно так же, как filter , за исключением того, что он удаляет элементы из массива, который вы передаете, а затем возвращает массив удаленных элементов из самого метода.

Нижнее подчеркивание

В служебной библиотеке Underscore есть метод, аналогичный Lodash, который называется reject . Он работает очень похоже, за исключением одного заметного различия. Результирующий массив возвращается из метода, а массив, который вы ему передаете, остается неизменным.

См. Пример в следующем коде:

 var arr = [1, 2, 3, 3, 4, 5]; 
 var ret = _.reject(arr, function(e) { 
 return e === 3; 
 }); 
 console.log(arr); 
 console.log(ret); 
 
 // Output: 
 // [ 1, 2, 3, 3, 4, 5 ] 
 // [ 1, 2, 4, 5 ] 

Опять же, как и метод remove reject лучше всего подходит для более сложных случаев, таких как удаление объектов или групп элементов.

Поддержка Internet Explorer

Если ваш проект требует от вас поддержки старых версий Internet Explorer, в частности IE 8 в данном случае, тогда метод indexOf() не будет работать для вас, поскольку он не поддерживается в этой версии IE.

Чтобы справиться с этим, одним из решений является использование прокладки для метода, как показано в этом ответе на переполнение стека :

 if (!Array.prototype.indexOf) 
 { 
 Array.prototype.indexOf = function(elt /*, from*/) 
 { 
 var len = this.length >>> 0; 
 
 var from = Number(arguments[1]) || 0; 
 from = (from < 0) 
 ? Math.ceil(from) 
 : Math.floor(from); 
 if (from < 0) 
 from += len; 
 
 for (; from < len; from++) 
 { 
 if (from in this && 
 this[from] === elt) 
 return from; 
 } 
 return -1; 
 }; 
 } 

Согласно сообщению SO, это реализация indexOf из MDN, используемая в Firefox / SpiderMonkey.

Другой вариант - использовать метод $.inArray()

 var arr = [1, 2, 3, 3, 4, 5]; 
 var idx = $.inArray(3, arr); 
 console.log(idx); 
 
 // Output: 
 // 2 

Это примерно эквивалентно indexOf , которое затем можно использовать для написания removeElement как показано в первом разделе этой статьи.

comments powered by Disqus