Удаление элементов массива в JavaScript - удаление vs-сращивания

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

Например:

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

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

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

Ответ 1

delete удалит свойство объекта, но не переиндексирует массив или не обновляет его длину. Это означает, что он выглядит как undefined:

> myArray = ['a', 'b', 'c', 'd']
  ["a", "b", "c", "d"]
> delete myArray[0]
  true
> myArray[0]
  undefined

Обратите внимание, что на самом деле оно не установлено в значение undefined, скорее свойство удаляется из массива, что делает его undefined. Инструменты Chrome dev делают это различие прозрачным, печатая empty при регистрации массива.

> myArray[0]
  undefined
> myArray
  [empty, "b", "c", "d"]

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

> myArray = ['a', 'b', 'c', 'd']
  ["a", "b", "c", "d"]
> myArray.splice(0, 2)
  ["a", "b"]
> myArray
  ["c", "d"]

Ответ 2

Метод Array.remove()

John Resig, создатель jQuery создал очень удобный метод Array.remove, который я всегда использую в своих проектах.

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

и вот несколько примеров того, как это можно использовать:

// Remove the second item from the array
array.remove(1);
// Remove the second-to-last item from the array
array.remove(-2);
// Remove the second and third items from the array
array.remove(1,2);
// Remove the last and second-to-last items from the array
array.remove(-2,-1);

Веб-сайт John

Ответ 3

Поскольку удаление только удаляет объект из элемента в массиве, длина массива не изменится. Splice удаляет объект и сокращает массив.

В следующем коде будут отображаться символы "a", "b", "undefined", "d"

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

for (var count = 0; count < myArray.length; count++) {
    alert(myArray[count]);
}

В то время как это будет отображать "a", "b", "d"

myArray = ['a', 'b', 'c', 'd']; myArray.splice(2,1);

for (var count = 0; count < myArray.length; count++) {
    alert(myArray[count]);
}

Ответ 4

Я наткнулся на этот вопрос, пытаясь понять, как удалить каждое вхождение элемента из массива. Здесь сравнение splice и delete для удаления каждого 'c' из массива items.

var items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];

while (items.indexOf('c') !== -1) {
  items.splice(items.indexOf('c'), 1);
}

console.log(items); // ["a", "b", "d", "a", "b", "d"]

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

while (items.indexOf('c') !== -1) {
  delete items[items.indexOf('c')];
}

console.log(items); // ["a", "b", undefined, "d", "a", "b", undefined, "d"]
​

Ответ 5

От Ссылка на Core JavaScript 1.5 > Операторы > Специальные операторы > delete Operator:

Когда вы удаляете элемент массива, длина массива не изменяется. Для Например, если вы удалите [3], [4] еще [4], а [3] - undefined. Эта сохраняется, даже если вы удалите последний элемент массива (удалить а [a.length-1]).

Ответ 6

splice будет работать с числовыми индексами.

тогда как delete можно использовать против других типов индексов.

Пример:

delete myArray['text1'];

Ответ 7

Возможно, стоит упомянуть, что сращивание работает только с массивами. (Свойства объекта нельзя полагаться на последовательный порядок.)

Чтобы удалить пару ключ-значение из объекта, удалить на самом деле то, что вы хотите:

delete myObj.propName;     // , or:
delete myObj["propName"];  // Equivalent.

Ответ 8

Как указано много раз выше, использование splice() кажется идеальным сочетанием. Документация в Mozilla:

Метод splice() изменяет содержимое массива, удаляя существующие элементы и/или добавляя новые элементы.

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

myFish.splice(2, 0, 'drum'); 
// myFish is ["angel", "clown", "drum", "mandarin", "sturgeon"]

myFish.splice(2, 1); 
// myFish is ["angel", "clown", "mandarin", "sturgeon"]

Синтаксис

array.splice(start)
array.splice(start, deleteCount)
array.splice(start, deleteCount, item1, item2, ...)

Параметры

начало

Индекс, с которого нужно начинать изменять массив. Если значение больше длины массива, фактический начальный индекс будет установлен на длину массива. Если отрицательный, начнется с того, что многие элементы с конца.

deleteCount

Целое число, указывающее количество старых элементов массива для удаления. Если deleteCount равно 0, элементы не удаляются. В этом случае вы должны указать хотя бы один новый элемент. Если deleteCount больше, чем количество элементов, оставшихся в массиве, начиная с начала, все элементы в конце массива будут удалены.

Если deleteCount опущен, deleteCount будет равен (arr.length - start).

item1, item2,...

Элементы для добавления в массив, начиная с начального индекса. Если вы не укажете какие-либо элементы, splice() будет удалять только элементы из массива.

Возвращаемое значение

Массив, содержащий удаленные элементы. Если удаляется только один элемент, возвращается массив из одного элемента. Если элементы не удалены, возвращается пустой массив.

[...]

Ответ 9

удалить против сращивания

когда вы удаляете элемент из массива

var arr = [1,2,3,4]; delete arr[2]; //result [1, 2, 3:, 4]
console.log(arr)

Ответ 10

delete действует как ситуация реального мира, он просто удаляет элемент, но длина массива остается неизменной:

пример из node терминала:

> var arr = ["a","b","c","d"];
> delete arr[2]
true
> arr
[ 'a', 'b', , 'd', 'e' ]

Вот функция, чтобы удалить элемент массива по индексу, используя slice(), он принимает значение arr как первый arg и индекс члена, который вы хотите удалить, как второй аргумент. Как вы можете видеть, он фактически удаляет член массива и уменьшает длину массива на 1

function(arr,arrIndex){
    return arr.slice(0,arrIndex).concat(arr.slice(arrIndex + 1));
}

То, что делает вышеприведенная функция, включает все члены до индекса и все члены после индекса и объединяет их вместе и возвращает результат.

Ниже приведен пример использования вышеприведенной функции как модуля node, так как терминал будет полезен:

> var arr = ["a","b","c","d"]
> arr
[ 'a', 'b', 'c', 'd' ]
> arr.length
4 
> var arrayRemoveIndex = require("./lib/array_remove_index");
> var newArray = arrayRemoveIndex(arr,arr.indexOf('c'))
> newArray
[ 'a', 'b', 'd' ] // c ya later
> newArray.length
3

обратите внимание, что это не будет работать с одним массивом с обманами в нем, потому что indexOf ( "c" ) просто получит первое появление и только сплайсирует и удаляет найденный первый "c".

Ответ 11

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

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

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

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

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

Было бы неплохо, если бы вы могли использовать что-то вроде 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)
},

Ответ 12

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

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]

Ответ 13

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

myArray = myArray.filter(function(item){
    return item.anProperty != whoShouldBeDeleted
});

Ответ 14

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

Ответ 15

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

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"

Ответ 16

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

  • используя splice()

    arrayObject.splice(index, 1);

  • используя delete

    delete arrayObject[index];

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

Ответ 17

Разницу можно увидеть, зарегистрировав длину каждого массива после применения оператора 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.

Ответ 18

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

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

Позвольте сначала удалить:

delete arr[1];

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

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

пусто!, и пусть оно получится:

arr[1]; //undefined

Значит, просто удалено значение и теперь undefined, так что длина будет одинаковой, и она вернет true...

Пусть reset наш массив и сделает это с помощью сращивания на этот раз:

arr.splice(1, 1);

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

[1, 3, 4, 5];

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

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

Ответ 19

IndexOf принимает также ссылочный тип. Предположим следующий сценарий:

var arr = [{item: 1}, {item: 2}, {item: 3}];
var found = find(2, 3); //pseudo code: will return [{item: 2}, {item:3}]
var l = found.length;

while(l--) {
   var index = arr.indexOf(found[l])
      arr.splice(index, 1);
   }
   
console.log(arr.length); //1

Ответ 20

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

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

Ответ 21

Если нужный элемент находится посередине (скажем, мы хотим удалить 'c', индекс которого равен 1), вы можете использовать:

var arr = ['a','b','c'];
var indexToDelete = 1;
var newArray = arr.slice(0,indexToDelete).combine(arr.slice(indexToDelete+1, arr.length))

Ответ 22

Для тех, кто хочет использовать Lodash, можно использовать: myArray = _.without(myArray, itemToRemove)

Или как я использую в Angular2

import { without } from 'lodash';
...
myArray = without(myArray, itemToRemove);
...

Ответ 23

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

Ответ 24

Другие уже сравнили delete с splice.

Другое интересное сравнение - delete и undefined: удаленный элемент массива использует меньше памяти, чем тот, который просто установлен на undefined;

Например, этот код не будет завершен:

let y = 1;
let ary = [];
console.log("Fatal Error Coming Soon");
while (y < 4294967295)
{
    ary.push(y);
    ary[y] = undefined;
    y += 1;
}
console(ary.length);

Выдает эту ошибку:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.

Итак, как вы видите, undefined на самом деле занимает кучу памяти.

Однако, если вы также delete ary-item (вместо того, чтобы просто установить его в undefined), код будет медленно завершаться:

let x = 1;
let ary = [];
console.log("This will take a while, but it will eventually finish successfully.");
while (x < 4294967295)
{
    ary.push(x);
    ary[x] = undefined;
    delete ary[x];
    x += 1;
}
console.log('Success, array-length: ${ary.length}.');

Это крайние примеры, но они указывают на delete, что я нигде не видел упоминаний.

Ответ 25

function deleteFromArray(array, indexToDelete){
  var remain = new Array();
  for(var i in array){
    if(array[i] == indexToDelete){
      continue;
    }
    remain.push(array[i]);
  }
  return remain;
}

myArray = ['a', 'b', 'c', 'd'];
deleteFromArray(myArray , 0);

//result: myArray = ['b', 'c', 'd'];