어레이를 루프하여 아이템 삭제(루프 중단 없음)
것이 , 루프를 하면 다음과 같습니다.splice()
초정의되어 있지 않은지 확인할 수는 있지만, 더 우아한 방법이 있을 것 같습니다.그 목적은 단순히 항목을 삭제하고 계속하는 것입니다.
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
..splice()
인덱스를 인덱스를 건너뜁니다..length
을 사용하다
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,i
a a a.splice()
또는 단순히 역순으로 반복할 수도 있습니다.
var i = Auction.auctions.length
while (i--) {
...
if (...) {
Auction.auctions.splice(i, 1);
}
}
이렇게 하면 인덱싱은 현재 포인트에서 어레이의 끝까지의 항목에만 영향을 미치고 반복의 다음 항목은 현재 포인트보다 낮기 때문에 재인덱싱은 반복의 다음 항목에 영향을 주지 않습니다.
이것은 꽤 흔한 문제입니다.해결책은 루프를 거꾸로 돌리는 것입니다.
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
인덱스는 뒤로 이동해도 유지되기 때문에 끝부분에서 삭제해도 상관 없습니다.
처음부터가 아니라 루프를 통과할 때마다 길이를 재계산합니다.예를 들어 다음과 같습니다.
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
그래야 도를 넘지 않을 거야
EDIT: if 문에 감소분을 추가했습니다.
질문의 내용은 반복되는 어레이에서 요소를 삭제하는 것이지 요소를 효율적으로 제거하는 것이 아닙니다만, 같은 상황이라면 재고해야 한다고 생각합니다.
의 알고리즘의 는 「」입니다.O(n^2)
스플라이스 함수와 for 루프가 모두 어레이에 걸쳐 반복됩니다(스플라이스 함수는 최악의 경우 어레이의 모든 요소를 이동합니다).대신 필요한 요소를 새 어레이에 푸시한 다음 해당 어레이를 원하는 변수에 할당할 수 있습니다(반복된 상태임).
var newArray = [];
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
auction.seconds--;
if (!auction.seconds < 0) {
newArray.push(auction);
}
}
Auction.auctions = newArray;
ES2015부터는 모든 것을 한 줄에 넣을 수 있습니다.
Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);
Auction.auctions = Auction.auctions.filter(function(el) {
return --el["seconds"] > 0;
});
를 는, ES6+ 를 하는 만으로 해 주세요.Array.filter
방??
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
필터 반복 중에 배열 요소를 수정하는 것은 개체에만 적용되며 원시 값 배열에는 적용되지 않습니다.
다음은 이 단순한 선형 시간 문제에 대한 간단한 선형 시간 해결 방법입니다.
n = 100만인 이 스니펫을 실행하면 filterInPlace()에 대한 각 호출은 0.013 ~.016초 걸립니다.2차 해법(예: 승인된 답변)은 그 약 백만 배가 소요됩니다.
// Remove from array every item such that !condition(item).
function filterInPlace(array, condition) {
var iOut = 0;
for (var i = 0; i < array.length; i++)
if (condition(array[i]))
array[iOut++] = array[i];
array.length = iOut;
}
// Try it out. A quadratic solution would take a very long time.
var n = 1*1000*1000;
console.log("constructing array...");
var Auction = {auctions: []};
for (var i = 0; i < n; ++i) {
Auction.auctions.push({seconds:1});
Auction.auctions.push({seconds:2});
Auction.auctions.push({seconds:0});
}
console.log("array length should be "+(3*n)+": ", Auction.auctions.length)
filterInPlace(Auction.auctions, function(auction) {return --auction.seconds >= 0; })
console.log("array length should be "+(2*n)+": ", Auction.auctions.length)
filterInPlace(Auction.auctions, function(auction) {return --auction.seconds >= 0; })
console.log("array length should be "+n+": ", Auction.auctions.length)
filterInPlace(Auction.auctions, function(auction) {return --auction.seconds >= 0; })
console.log("array length should be 0: ", Auction.auctions.length)
이렇게 하면 새로운 어레이를 작성하는 것이 아니라 원래 어레이를 원래대로 변경할 수 있습니다.예를 들어 어레이가 프로그램의 단일 메모리 병목현상일 경우, 일시적으로라도 같은 크기의 어레이를 만들고 싶지 않습니다.
다음은 스플라이스를 올바르게 사용하기 위한 또 다른 예입니다.이 예에서는 'array'에서 'attribute'를 삭제하려고 합니다.
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
어레이 요소를 한 번 다이제스트하는 또 다른 간단한 솔루션:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
일반 for 루프가 더 익숙합니다. 배열에서 항목을 제거할 때마다 인덱스를 감소시키면 됩니다.
//5 trues , 5 falses
var arr1 = [false, false, true, true, false, true, false, true, true, false];
//remove falses from array
for (var i = 0; i < arr1.length; i++){
if (arr1[i] === false){
arr1.splice(i, 1);
i--;// decrement index if item is removed
}
}
console.log(arr1);// should be 5 trues
.splice에서 CPU 사이클을 낭비하는 이유는 무엇입니까?이 조작은, 어레이내의 요소를 삭제하기 위해서, 루프 전체를 몇번이나 반복해 실시할 필요가 있습니다.
하나의 루프에 기존의 2개의 깃발을 사용하면 어떨까요?
const elements = [1, 5, 5, 3, 5, 2, 4];
const remove = 5
i = 0
for(let j = 0; j < elements.length; j++){
if (elements[j] !== remove) {
elements[i] = elements[j]
i++
}
}
elements.length = i
루프 시 어레이를 newArray로 릴레이합니다.
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = [];
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
한 번 해봐
RemoveItems.forEach((i, j) => {
OriginalItems.splice((i - j), 1);
});
파라미터 삭제
oldJson=[{firstName:'s1',lastName:'v1'},
{firstName:'s2',lastName:'v2'},
{firstName:'s3',lastName:'v3'}]
newJson = oldJson.map(({...ele}) => {
delete ele.firstName;
return ele;
})
각 객체에서 분산 연산자를 사용할 때 원래 어레이 객체도 손상되지 않도록 삭제 및 새로운 어레이를 만듭니다.
기능하는 2가지 예:
예 1
// Remove from Listing the Items Checked in Checkbox for Delete
let temp_products_images = store.state.c_products.products_images
if (temp_products_images != null) {
for (var l = temp_products_images.length; l--;) {
// 'mark' is the checkbox field
if (temp_products_images[l].mark == true) {
store.state.c_products.products_images.splice(l,1); // THIS WORKS
// this.$delete(store.state.c_products.products_images,l); // THIS ALSO WORKS
}
}
}
예 2
// Remove from Listing the Items Checked in Checkbox for Delete
let temp_products_images = store.state.c_products.products_images
if (temp_products_images != null) {
let l = temp_products_images.length
while (l--)
{
// 'mark' is the checkbox field
if (temp_products_images[l].mark == true) {
store.state.c_products.products_images.splice(l,1); // THIS WORKS
// this.$delete(store.state.c_products.products_images,l); // THIS ALSO WORKS
}
}
}
이 실에는 이미 많은 훌륭한 해답들이 있다.그러나 ES5 컨텍스트에서 "n번째 요소 배열에서 제거"를 해결하려고 했을 때의 경험을 공유하고 싶었습니다.
JavaScript 배열에는 처음부터 끝까지 요소를 추가하거나 제거하는 방법이 있습니다.다음과 같습니다.
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
기본적으로 위의 방법 중 n번째 요소를 어레이에서 직접 제거하기 위해 사용할 수 있는 방법은 없습니다.
주의할 점은 이것이 반복 중에 컬렉션의 n번째 요소를 제거할 수 있는 Java 반복기와 대조된다는 것입니다.
으로는 어레이 입니다.Array.splice
요소 수 다른 이).n번째 요소 삭제는 다음과 같습니다.
Array.splice(index,1) - removes the element at the index
다음은 원래 답변(댓글 포함)에서 복사한 코드입니다.
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
또 다른 주목할 만한 방법은Array.slice
그러나 이 메서드의 반환 유형은 제거된 요소입니다.또, 원래의 어레이는 변경되지 않습니다.다음과 같이 코드 스니펫을 수정했습니다.
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
그렇긴 하지만, 우리는 여전히 사용할 수 있다.Array.slice
n번째 요소를 제거합니다.단, 훨씬 더 많은 코드(따라서 비효율적)
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
그
Array.slice
방법은 기능적 프로그래밍에서 불변성을 달성하기 위해 매우 중요하다.
그냥 훑어보고 사용하시면 됩니다.
언급URL : https://stackoverflow.com/questions/9882284/looping-through-array-and-removing-items-without-breaking-for-loop
'itsource' 카테고리의 다른 글
SQL 계산에서의 에일리어스 사용 (0) | 2022.10.05 |
---|---|
URL에서 파일 이름 가져오기 (0) | 2022.09.30 |
여러 DB 결과를 사용하여 MySQL replace를 선택 항목으로 실행하여 교착 상태 발생 (0) | 2022.09.30 |
venn 다이어그램으로 sql joins (0) | 2022.09.30 |
onChange of html 선택 시 매개 변수를 전달하는 방법 (0) | 2022.09.30 |