Удаление элементов массива в 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
В настоящее время существует два способа сделать это
Но я всегда предлагаю использовать сплайсинг для объектов массива и удалить атрибуты объекта, потому что 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'];