etc./StackOverFlow

JavaScript에서 배열 요소 삭제 - 삭제 대 스플라이스

청렴결백한 만능 재주꾼 2022. 3. 22. 11:03
반응형

질문자 :lYriCAlsSH


Array.splice 메서드를 사용하는 것과 반대로 배열 요소 에서 delete 연산자 를 사용하는 것의 차이점은 무엇입니까?

예를 들어:

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

객체로 할 수 있는 것처럼 배열 요소를 삭제할 수 있는데 왜 splice 메서드가 있습니까?



delete 는 객체 속성을 삭제하지만 배열을 다시 인덱싱하거나 길이를 업데이트하지 않습니다. 이렇게 하면 정의되지 않은 것처럼 보입니다.

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

Andy Hume

Array.remove() 메서드

jQuery의 창시자인 John Resig 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);

존의 웹사이트


Mohsen

삭제는 배열의 요소에서 개체만 제거하므로 배열의 길이는 변경되지 않습니다. 스플라이스는 객체를 제거하고 배열을 줄입니다.

다음 코드는 "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]); }

andynormancx

배열에서 요소의 모든 발생을 제거하는 방법을 이해하려고 시도하는 동안 이 질문을 우연히 발견했습니다. 다음은 items 배열 'c' 를 제거하기 위한 splicedelete 의 비교 입니다.

 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"]​

Troy Harvey

Core JavaScript 1.5 참조 > 연산자 > 특수 연산자 > 연산자 삭제 :

배열 요소를 삭제해도 배열 길이는 영향을 받지 않습니다. 예를 들어, a[3]을 삭제하면 a[4]는 여전히 a[4]이고 a[3]은 정의되지 않습니다. 이것은 배열의 마지막 요소를 삭제하더라도 유지됩니다(delete a[a.length-1]).


f3lix

위에서 여러 번 언급했듯이 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() 는 배열에서 요소만 제거합니다.

반환 값

삭제된 요소를 포함하는 배열입니다. 한 요소만 제거되면 한 요소의 배열이 반환됩니다. 요소가 제거되지 않으면 빈 배열이 반환됩니다.

[...]


serv-inc

splice 는 숫자 인덱스와 함께 작동합니다.

반면 delete 는 다른 종류의 인덱스에 대해 사용할 수 있습니다.

예시:

 delete myArray['text1'];

Gopal

splice는 배열에서만 작동한다는 점도 언급할 가치가 있습니다. (객체 속성은 일관된 순서를 따르는 데 의존할 수 없습니다.)

객체에서 키-값 쌍을 제거하려면 삭제가 실제로 원하는 것입니다.

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

jtrick

대 스플라이스 삭제

배열에서 항목을 삭제할 때

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

삭제 의 경우 요소가 삭제 되지만 인덱스는 비어 있습니다.

splice 요소가 삭제되고 나머지 요소의 인덱스가 그에 따라 감소하는 경우


Ashish Yadav

delete 는 실제 상황이 아닌 것처럼 작동 하며 항목만 제거 하지만 배열 길이는 동일하게 유지됩니다.

노드 터미널의 예:

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

다음은 slice() 를 사용하여 인덱스별로 배열의 항목을 제거하는 함수입니다. 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"만 스플라이스하고 제거하기 때문에 이것은 속임수가 있는 하나의 배열에서 작동하지 않는다는 점에 유의하십시오.


med116

큰 배열을 반복하고 요소를 선택적으로 삭제하려면 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) },

Mike T

당신은 이것과 같은 것을 사용할 수 있습니다

 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]


Zeeshan Saleem

왜 그냥 필터링하지 않습니까? js에서 배열을 고려하는 가장 명확한 방법이라고 생각합니다.

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

Asqan

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입니다.


underthecode

다른 사람들은 이미 deletesplice 적절하게 비교했습니다.

또 다른 흥미로운 비교는 deleteundefined 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 실제로 힙 메모리를 차지하는 것을 볼 수 있습니다.

그러나 ary-item delete 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


Lonnie Best

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


Terry Lin

그들은 다른 목적을 가진 다른 것들입니다.

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


* (제 빈약한 블로그에 올라온 글입니다)


T.J. Crowder

현재 이 작업을 수행하는 두 가지 방법이 있습니다.

  1. splice() 사용

    arrayObject.splice(index, 1);

  2. 삭제 사용

    delete arrayObject[index];

그러나 삭제는 배열 길이를 업데이트하지 않기 때문에 항상 배열 객체에 스플라이스를 사용하고 객체 속성에 삭제를 사용하는 것이 좋습니다.


imal hasaranga perera

자, 아래와 같은 배열이 있다고 상상해 보세요.

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

먼저 삭제를 수행해 보겠습니다.

 delete arr[1];

결과는 다음과 같습니다.

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

비어있는! 그리고 그것을 얻자:

 arr[1]; //undefined

따라서 값이 삭제되고 지금은 정의되지 않았 으므로 길이가 동일하고 true 를 반환한다는 의미입니다.

배열을 재설정하고 이번에는 splice로 수행해 보겠습니다.

 arr.splice(1, 1);

그리고 이것은 이번에 결과입니다:

 [1, 3, 4, 5];

배열 길이가 변경되었고 arr[1]3인 것을 볼 수 있습니다...

또한 이 경우 [3] 배열에서 삭제된 항목을 반환합니다...


Alireza

배열이 작은 경우 filter 를 사용할 수 있습니다.

 myArray = ['a', 'b', 'c', 'd']; myArray = myArray.filter(x => x !== 'b');

Emir Mamashov

성능

기능적 차이점에 대한 좋은 답변이 이미 많이 있습니다. 따라서 여기서는 성능에 초점을 맞추고 싶습니다. 오늘(2020.06.25) 문제에서 언급한 솔루션과 추가로 선택한 답변에서 Chrome 83.0, Safari 13.1 및 Firefox 77.0에 대한 테스트를 수행합니다.

결론

  • splice (B) 솔루션은 크고 작은 어레이에 대해 빠릅니다.
  • delete (A) 솔루션은 큰 배열의 경우 가장 빠르고 작은 배열의 경우 중간 빠름
  • filter (E) 솔루션은 작은 어레이의 경우 Chrome 및 Firefox에서 가장 빠릅니다(그러나 Safari에서 가장 느리고 큰 어레이의 경우 느림).
  • 솔루션 D는 매우 느립니다.
  • 솔루션 C는 Chrome 및 Safari의 큰 배열에서 작동하지 않습니다.
     function C(arr, idx) { var rest = arr.slice(idx + 1 || arr.length); arr.length = idx < 0 ? arr.length + idx : idx; arr.push.apply(arr, rest); return arr; } // Crash test let arr = [...'abcdefghij'.repeat(100000)]; // 1M elements try { C(arr,1) } catch(e) {console.error(e.message)}

여기에 이미지 설명 입력

세부

솔루션 A B C D E(my)에 대해 다음 테스트를 수행합니다.

 function A(arr, idx) { delete arr[idx]; return arr; } function B(arr, idx) { arr.splice(idx,1); return arr; } function C(arr, idx) { var rest = arr.slice(idx + 1 || arr.length); arr.length = idx < 0 ? arr.length + idx : idx; arr.push.apply(arr, rest); return arr; } function D(arr,idx){ return arr.slice(0,idx).concat(arr.slice(idx + 1)); } function E(arr,idx) { return arr.filter((a,i) => i !== idx); } myArray = ['a', 'b', 'c', 'd']; [A,B,C,D,E].map(f => console.log(`${f.name} ${JSON.stringify(f([...myArray],1))}`));
 This snippet only presents used solutions

Chrome에 대한 예시 결과

여기에 이미지 설명 입력


Kamil Kiełczewski

가장 쉬운 방법은 아마도

 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


Prashanth

Lodash 를 사용하려는 사람들은 다음을 사용할 수 있습니다. myArray = _.without(myArray, itemToRemove)

또는 Angular2에서 사용하는 것처럼

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

Ricky Levi

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

Srikrushna

삭제하려는 요소가 중간에 있으면(인덱스가 1인 'c'를 삭제하려는 경우) 다음을 사용할 수 있습니다.

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

Idan Gozlan

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

roland

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


Eyad Farra

출처 : http:www.stackoverflow.com/questions/500606/deleting-array-elements-in-javascript-delete-vs-splice

반응형