Avatar ·

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

Всем привет! Только начал изучать JavaScript и столкнулся с проблемой. У меня есть массив с числами: ```javascript let numbers = [10, 20, 30, 40, 50]; ``` Я хочу удалить из него число 30. Пробовал использовать `delete numbers[2]`, но после этого в массиве остаётся пустое место (empty item), и длина массива не меняется. Потом я слышал про метод `splice()`, но не совсем понял, как он работает — он удаляет по индексу, а мне нужно удалить именно по значению. Если я не знаю точно, на какой позиции находится элемент, как быть? Ещё пробовал фильтровать через `filter()`, но мне кажется, что это создаёт новый массив, а не изменяет исходный. А мне нужно, чтобы оригинальный массив изменился. В общем, подскажите, пожалуйста, как правильно удалить элемент из массива по его значению, а не по индексу? И можно ли это сделать без создания нового массива? Буду благодарен за примеры кода. <<>>

Основное решение: комбинация indexOf() и splice()

Самый популярный и надёжный способ удалить элемент из массива по его значению — использовать indexOf() для поиска индекса, а затем splice() для удаления. Этот метод изменяет исходный массив, что соответствует вашему требованию.

let numbers = [10, 20, 30, 40, 50];
let itemToRemove = 30;

let index = numbers.indexOf(itemToRemove);
if (index !== -1) {
    numbers.splice(index, 1);
}

console.log(numbers); // [10, 20, 40, 50]

Как это работает:

  • indexOf() возвращает первый индекс, по которому встречается указанное значение. Если элемента нет — возвращает -1.
  • splice(index, 1) удаляет 1 элемент, начиная с найденного индекса.
  • Проверка if (index !== -1) обязательна, чтобы не вызвать ошибку, если элемент отсутствует в массиве.

Если в массиве несколько одинаковых элементов

Если нужно удалить ВСЕ вхождения элемента, используйте цикл while:

let numbers = [10, 20, 30, 30, 40, 50];
let itemToRemove = 30;

let index = numbers.indexOf(itemToRemove);
while (index !== -1) {
    numbers.splice(index, 1);
    index = numbers.indexOf(itemToRemove);
}

console.log(numbers); // [10, 20, 40, 50]

Современный альтернативный метод (ES6+)

Если вы не против создать новый массив, можно использовать filter(). Хотя он не изменяет исходный массив, во многих ситуациях это даже предпочтительнее (иммутабельность данных):

let numbers = [10, 20, 30, 40, 50];
let itemToRemove = 30;

let filteredNumbers = numbers.filter(item => item !== itemToRemove);
console.log(filteredNumbers); // [10, 20, 40, 50]
console.log(numbers); // [10, 20, 30, 40, 50] — исходный не изменился

Если нужно присвоить результат обратно в ту же переменную, просто перезапишите её:

numbers = numbers.filter(item => item !== itemToRemove);

Для удаления по сложным условиям (объекты, глубокое сравнение)

Когда элементы — объекты, indexOf() не сработает, так как сравнивает по ссылке. Используйте findIndex():

let users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
];

let userIdToRemove = 2;
let index = users.findIndex(user => user.id === userIdToRemove);

if (index !== -1) {
    users.splice(index, 1);
}

console.log(users); // [{ id: 1, name: 'Alice' }, { id: 3, name: 'Charlie' }]

Важно: indexOf() использует строгое сравнение (===), поэтому для удаления числа 30 из массива ['30', 30] он найдёт только число, но не строку.

<<>>

Удаление последнего или первого вхождения

Если нужно удалить не первое, а последнее вхождение элемента, используйте lastIndexOf() вместо indexOf():

let numbers = [10, 20, 30, 40, 30, 50];
let itemToRemove = 30;

let lastIndex = numbers.lastIndexOf(itemToRemove);
if (lastIndex !== -1) {
    numbers.splice(lastIndex, 1);
}

console.log(numbers); // [10, 20, 30, 40, 50] — удалил последнюю 30

Использование функции для переиспользования

Оберните логику в удобную функцию, чтобы не писать одно и то же каждый раз:

function removeItemFromArray(arr, item) {
    let index = arr.indexOf(item);
    if (index !== -1) {
        arr.splice(index, 1);
    }
    return arr;
}

let fruits = ['apple', 'banana', 'orange'];
removeItemFromArray(fruits, 'banana');
console.log(fruits); // ['apple', 'orange']

Производительность

Для больших массивов (более 10 000 элементов) filter() может работать быстрее, чем цикл с splice(), так как splice() вызывает переиндексацию всех последующих элементов. Но для повседневных задач разница незаметна. Выбирайте подход исходя из читаемости кода и необходимости мутировать исходный массив.