Вопрос: Как удалить определенный элемент из массива в JavaScript?


У меня есть массив целых чисел, и я использую .push()метод для добавления к нему элементов.

Есть ли простой способ удалить определенный элемент из массива? Эквивалент чего-то вроде array.remove(int);,

Я должен использовать ядро JavaScript - нет рамки разрешены.


5906


источник


Ответы:


Найти indexэлемента массива, который вы хотите удалить, затем удалите этот индекс с помощью splice,

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

Второй параметр splice- количество элементов для удаления. Обратите внимание, что spliceизменяет массив на месте и возвращает новый массив, содержащий удаленные элементы.


Заметка : поддержка браузера для indexOf ограничено


8657



Я не знаю, как вы ожидаете 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];

848



Отредактировано 2016 октября

  • Сделайте это простым, интуитивным и явным ( https://en.wikipedia.org/wiki/Occam%27s_razor )
  • Сделайте это неизменным (исходный массив останется без изменений)
  • Сделайте это со стандартными функциями JS, если ваш браузер их не поддерживает - использовать полипол

В этом примере кода я использую "Array.filter (...)" чтобы удалить ненужные элементы из массива, эта функция не изменяет исходный массив и создает новый. Если ваш браузер не поддерживает эту функцию (например, IE до версии 9 или Firefox до версии 1.5), рассмотрите возможность использования фильтрующий полипол из Mozilla ,

Удаление элемента (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 ]

ВАЖНЫЙ «Функция array.includes (...)» вообще не поддерживается в IE, Chrome до версии 47, Firefox до версии 43, Safari до версии 9 и Edge до 14 версии, поэтому здесь полипол из Mozilla

Удаление нескольких элементов (передовой экспериментальный 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 :)

Справка


628



Зависит от того, хотите ли вы сохранить пустое место или нет.

Если вам нужен пустой слот, удаление будет прекрасным:

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, если не найден.


343



A friend was having issues in Internet Explorer 8, and showed me what he did. I told him it was wrong, and he told me he got the answer here. The current top answer will not work in all browsers (Internet Explorer 8 for example), and it will only remove the first occurrence of the item.

Remove ALL instances from an array

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

It loops through the array backwards (since indices and length will change as items are removed) and removes the item if it's found. It works in all browsers.


212



There are two major approaches:

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

  2. delete: delete anArray[index];

Be careful when you use delete for an array. It is good for deleting attributes of objects but not so good for arrays. It is better to use splice for arrays.

Keep in mind that when you use delete for an array you could get wrong results for anArray.length. In other words, delete would remove the element but wouldn't update the value of length property.

You can also expect to have holes in index numbers after using delete, e.g. you could end up with having indexes 1,3,4,8,9,11 and length as it was before using delete. In that case, all indexed for loops would crash, since indexes are no longer sequential.

If you are forced to use delete for some reason, then you should use for each loops when you need to loop through arrays. As the matter of fact, always avoid using indexed for loops, if possible. That way the code would be more robust and less prone to problems with indexes.


123



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)


95



There is no need to use indexOf or splice. However, it performs better if you only want to remove one occurrence of an element.

Find and move (move):

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

Use indexOf and splice (indexof):

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

Use only splice (splice):

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

Run-times on nodejs for array with 1000 elements (average over 10000 runs):

indexof is approximately 10x slower than move. Even if improved by removing the call to indexOf in splice it performs much worse than 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

76



Too old to reply, but may it help someone, by providing a predicate instead of a value.

NOTE: it will update the given array, and return affected rows

Usage

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

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

Definition

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

51



John Resig 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);
};

If you don’t want to extend a global object, you can do something like the following, instead:

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

But the main reason I am posting this is to warn users against the alternative implementation suggested in the comments on that page (Dec 14, 2007):

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

It seems to work well at first, but through a painful process I discovered it fails when trying to remove the second to last element in an array. For example, if you have a 10-element array and you try to remove the 9th element with this:

myArray.remove(8);

You end up with an 8-element array. Don't know why but I confirmed John's original implementation doesn't have this problem.


47