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

StackOverflow https://stackoverflow.com/questions/500606

Вопрос

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

Например:

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

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

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

Это было полезно?

Решение

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

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

Обратите внимание, что на самом деле оно не установлено в значение undefined, скорее свойство удаляется из массива , что делает его появиться неопределенный.Инструменты разработки Chrome проясняют это различие, выводя 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"]

Другие советы

Метод Array.remove()

Джон Уходит в отставку, создатель 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]);
}

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

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

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

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

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

пример:

delete myArray['text1'];

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

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

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 равно 0, никакие элементы не удаляются.В этом случае вы должны указать хотя бы один новый элемент.Если deleteCount больше, чем количество элементов, оставшихся в массиве, начиная с начала, то все элементы до конца массива будут удалены.

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

пункт 1, пункт 2, ...

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

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

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

[...]

удаление Против сращивания

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

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

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

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

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

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

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

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

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

Вот функция для удаления элемента массива по индексу, использующая нарезать (), он принимает arr в качестве первого аргумента и индекс элемента, который вы хотите удалить, в качестве второго аргумента.Как вы можете видеть, это фактически удаляет элемент массива и уменьшает длину массива на 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".

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

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

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

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

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]

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

myArray = myArray.filter(function(item){
    return item.anProperty != whoShouldBeDeleted
});
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".Это неверно.IT удаляет запись (свойство) полностью, оставляя пробел.

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

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 arrayObject[index];

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

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

способ соединения()

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.

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

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

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

delete arr[1];

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

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

пусто! и давайте разберемся с этим:

arr[1]; //undefined

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

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

arr.splice(1, 1);

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

[1, 3, 4, 5];

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

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

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

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

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

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

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

Удалить:удаление приведет к удалению свойства объекта, но не приведет к переиндексации массива или обновлению его длины.Это создает впечатление, что это не определено:

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top