Удаление элементов массива в JavaScript - удаление против сращивания - PullRequest
1277 голосов
/ 01 февраля 2009

В чем разница между использованием оператора delete в элементе массива и использованием метода Array.splice ?

Например:

myArray = ['a', 'b', 'c', 'd'];

delete myArray[1];
//  or
myArray.splice (1, 1);

Зачем даже метод сращивания, если я могу удалять элементы массива, как я могу с объектами?

Ответы [ 24 ]

6 голосов
/ 24 мая 2012

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

Вы можете сделать это, создав новый массив. * например 1003 *

function reindexArray( array )
{
       var result = [];
        for( var key in array )
                result.push( array[key] );
        return result;
};

Но я не думаю, что вы можете изменить значения ключей в исходном массиве, что было бы более эффективно - похоже, вам, возможно, придется создать новый массив.

Обратите внимание, что вам не нужно проверять "неопределенные" записи, так как они на самом деле не существуют и цикл for не возвращает их. Это артефакт печати массива, который отображает их как неопределенные. Похоже, они не существуют в памяти.

Было бы неплохо, если бы вы могли использовать что-то вроде slice (), которое было бы быстрее, но оно не переиндексируется. Кто-нибудь знает лучший способ?


На самом деле, вы, вероятно, можете сделать это на месте следующим образом, что, вероятно, является более эффективным, с точки зрения производительности:

reindexArray : function( array )
{
    var index = 0;                          // The index where the element should be
    for( var key in array )                 // Iterate the array
    {
        if( parseInt( key ) !== index )     // If the element is out of sequence
        {
            array[index] = array[key];      // Move it to the correct, earlier position in the array
            ++index;                        // Update the index
        }
    }

    array.splice( index );  // Remove any remaining elements (These will be duplicates of earlier items)
},
5 голосов
/ 26 ноября 2013

вы можете использовать что-то вроде этого

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';})); // [1,2,3,4,6]
2 голосов
/ 31 января 2019

Разницу можно увидеть, зарегистрировав длину каждого массива после применения оператора delete и метода splice(). Например:

оператор удаления

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];

console.log(trees); // ["redwood", "bay", "cedar", empty, "maple"]
console.log(trees.length); // 5

Оператор delete удаляет элемент из массива, но «заполнитель» элемента все еще существует. oak был удален, но он все еще занимает место в массиве. Из-за этого длина массива остается 5.

метод splice ()

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);

console.log(trees); // ["redwood", "bay", "cedar", "maple"]
console.log(trees.length); // 4

Метод splice() полностью удаляет целевое значение и также как "заполнитель". oak был удален, а также пространство, которое он занимал в массиве. Длина массива теперь равна 4.

2 голосов
/ 19 февраля 2017

Это разные вещи, которые имеют разные цели.

splice зависит от массива и, когда используется для удаления, удаляет записи из массива , а перемещает все предыдущие записи вверх, чтобы заполнить пробел. (Он также может быть использован для вставки записей или обоих одновременно.) splice изменит length массива (при условии, что это не вызов no-op: theArray.splice(x, 0)).

delete не зависит от массива; он предназначен для использования на объектах: он удаляет свойство (пара ключ / значение) из объекта, на котором вы его используете. Это применимо только к массивам, потому что стандартные (например, нетипизированные) массивы в JavaScript на самом деле вообще не являются массивами *, это объекты со специальной обработкой для определенных свойств, например, для имен которых "" индексы массива "(которые определены как имена строк" ... чье числовое значение i находится в диапазоне +0 ≤ i < 2^32-1 ") и length Когда вы используете delete для удаления записи массива, все, что он делает, это удаляет запись; он не перемещает другие записи, следующие за ним, чтобы заполнить пробел, и поэтому массив становится "разреженным" (некоторые записи полностью отсутствуют). Не влияет на length.

В паре текущих ответов на этот вопрос неправильно указано, что при использовании delete "вводится значение undefined". Это не правильно. полностью удаляет запись (свойство), оставляя пробел.

Давайте использовать некоторый код, чтобы проиллюстрировать различия:

console.log("Using `splice`:");
var a = ["a", "b", "c", "d", "e"];
console.log(a.length);            // 5
a.splice(0, 1);
console.log(a.length);            // 4
console.log(a[0]);                // "b"

console.log("Using `delete`");
var a = ["a", "b", "c", "d", "e"];
console.log(a.length);            // 5
delete a[0];
console.log(a.length);            // still 5
console.log(a[0]);                // undefined
console.log("0" in a);            // false
console.log(a.hasOwnProperty(0)); // false

console.log("Setting to `undefined`");
var a = ["a", "b", "c", "d", "e"];
console.log(a.length);            // 5
a[0] = undefined;
console.log(a.length);            // still 5
console.log(a[0]);                // undefined
console.log("0" in a);            // true
console.log(a.hasOwnProperty(0)); // true

* (это пост в моем анемичном небольшом блоге)

2 голосов
/ 20 апреля 2017

В настоящее время есть два способа сделать это

  1. с использованием splice ()

    arrayObject.splice(index, 1);

  2. используя delete

    delete arrayObject[index];

Но я всегда предлагаю использовать соединение для объектов массива и удалять для атрибутов объектов, потому что удаление не обновляет длину массива.

2 голосов
/ 21 июля 2016
function remove_array_value(array, value) {
    var index = array.indexOf(value);
    if (index >= 0) {
        array.splice(index, 1);
        reindex_array(array);
    }
}
function reindex_array(array) {
   var result = [];
    for (var key in array) {
        result.push(array[key]);
    }
    return result;
}

пример:

var example_arr = ['apple', 'banana', 'lemon'];   // length = 3
remove_array_value(example_arr, 'banana');

банан удален, а длина массива = 2

2 голосов
/ 17 марта 2016

Почему бы просто не фильтровать? Я думаю, что это самый понятный способ рассмотреть массивы в js.

myArray = myArray.filter(function(item){
    return item.anProperty != whoShouldBeDeleted
});
1 голос
/ 25 декабря 2017

ОК, представьте, что у нас есть этот массив ниже:

const arr = [1, 2, 3, 4, 5];

Давайте сначала удалим:

delete arr[1];

и вот результат:

[1, empty, 3, 4, 5];

пусто! и давайте получим:

arr[1]; //undefined

То есть означает только удаленное значение, и теперь оно не определено , поэтому длина такая же, и он вернет true ...

Давайте сбросим наш массив и на этот раз сделаем это со сращиванием:

arr.splice(1, 1);

и вот результат на этот раз:

[1, 3, 4, 5];

Как вы видите, длина массива изменилась и arr[1] равно 3 сейчас ...

Также это вернет удаленный элемент в массиве, который в данном случае равен [3] ...

0 голосов
/ 20 июля 2015

Самый простой способ, вероятно,

var myArray = ['a', 'b', 'c', 'd'];
delete myArray[1]; // ['a', undefined, 'c', 'd']. Then use lodash compact method to remove false, null, 0, "", undefined and NaN
myArray = _.compact(myArray); ['a', 'c', 'd'];

Надеюсь, это поможет. Справка: https://lodash.com/docs#compact

0 голосов
/ 28 июня 2018

delete : delete удалит свойство объекта, но не будет переиндексировать массив или обновить его длину. Это делает это, как будто это не определено:

splice : фактически удаляет элемент, переиндексирует массив и изменяет его длина.

Удалить элемент из последнего

arrName.pop();

Удалить элемент из первого

arrName.shift();

Удалить из середины

arrName.splice(starting index,number of element you wnt to delete);

Ex: arrName.splice(1,1);

Удалить один элемент из последнего

arrName.splice(-1);

Удалить, используя индексный номер массива

 delete arrName[1];
...