Удаление элементов массива в JavaScript-delete vs splice

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

например:

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

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

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

23 ответов


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

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

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

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

myArray.splice(start, deleteCount) на самом деле удаляет element, оленей массив, и изменяет его длину.

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

массив.удалить() метод

Джон В Отставку, создатель 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);

Джон


поскольку delete удаляет только объект из элемента в массиве, длина массива не изменится. 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]);
}

я наткнулся на этот вопрос, пытаясь понять, как удалить каждое вхождение элемента из массива. вот сравнение of 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"]
​

с Core JavaScript 1.5 справка > операторы > специальные операторы > удалить оператор :

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


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

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

пример:

delete myArray['text1'];

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

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

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

как говорилось много раз выше, используя 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).

элемент1, место № 2, ...

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

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

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

[...]


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

пример из терминальных узлов:

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

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

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

> 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", которую он найдет.


удалить Vs splice

при удалении элемента из массива

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

когда вы соединяете

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

в случае удалить на элемент удаляется но остается пустым

в случае соединение элемент удаляется, а индекс остальных элементов уменьшается соответственно


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

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]


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

Вы можете сделать это путем создания нового массива. е.г

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)
},

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


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

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

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


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

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

    arrayObject.splice(index, 1);

  2. использование delete

    delete arrayObject[index];

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


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

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

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

delete arr[1];

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

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

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

arr[1]; //undefined

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

давайте сбросим наш массив и сделаем это с помощью splice на этот раз:

arr.splice(1, 1);

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

[1, 3, 4, 5];

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

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


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

иначе:

var item2 = findUnique(2); //will return {item: 2}
var l = arr.length;
var found = false;
  while(!found && l--) {
  found = arr[l] === item2;
}

console.log(l, arr[l]);// l is index, arr[l] is the item you look for

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

var arr = ['a','b','c'];

Вы можете использовать: var indexToDelete = 1; var newArray = arr.slice(0, indexToDelete).combine(arr.slice(indexToDelete+1, arr.length))


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

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


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

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

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

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

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

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

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

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

arrName.pop();

удалить элемент из first

arrName.shift();

удалить из средний

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

Ex: arrName.splice(1,1);

удалить один элемент из последней

arrName.splice(-1);

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

 delete arrName[1];

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

/ / результат: myArray = ['b',' c','d'];