Удаление элементов массива в 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
* (это сообщение в моем маленьком анемичном блоге)
В настоящее время есть два способа сделать это
-
использование splice ()
arrayObject.splice(index, 1);
-
использование 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'];