[javascript] forEach 루프의 배열에서 요소를 제거하는 방법은 무엇입니까?

forEach루프 의 배열에서 요소를 제거하려고하는데 내가 본 표준 솔루션에 문제가 있습니다.

이것이 내가 현재 시도하고있는 것입니다.

review.forEach(function(p){
   if(p === '\u2022 \u2022 \u2022'){
      console.log('YippeeeE!!!!!!!!!!!!!!!!')
      review.splice(p, 1);
   }
});

콘솔에서 if보고 있기 때문에 안으로 들어가는 것을 알고 있습니다 YippeeeeeE!!!!!!!!!!!!!.

내 문제 : for 루프와 논리가 건전하다는 것을 알고 있지만 배열에서 현재 요소를 제거하려는 시도가 실패했습니다.

최신 정보:

Xotic750의 답변을 시도했지만 요소가 여전히 제거되지 않았습니다.

내 코드의 기능은 다음과 같습니다.

review.forEach(function (item, index, object) {
    if (item === '\u2022 \u2022 \u2022') {
       console.log('YippeeeE!!!!!!!!!!!!!!!!')
       object.splice(index, 1);
    }
    console.log('[' + item + ']');
});

다음은 배열이 여전히 제거되지 않은 출력입니다.

[Scott McNeil]
[reviewed 4 months ago]
[ Mitsubishi is AMAZING!!!]
YippeeeE!!!!!!!!!!!!!!!!
[•  •]

따라서 분명히 지시 된대로 if 문으로 들어가지만 [• • •]가 여전히 거기에 있다는 것도 분명합니다.



답변

이 작업을하려는 것 같습니까?

Array.prototype.splice를 사용하여 배열 반복 및 변경

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'b', 'c', 'b', 'a'];

review.forEach(function(item, index, object) {
  if (item === 'a') {
    object.splice(index, 1);
  }
});

log(review);
<pre id="out"></pre>

인접한 배열 항목과 동일한 값이 2 개없는 간단한 경우에는 잘 작동합니다. 그렇지 않으면이 문제가 발생합니다.

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.forEach(function(item, index, object) {
  if (item === 'a') {
    object.splice(index, 1);
  }
});

log(review);
<pre id="out"></pre>

그렇다면 배열을 반복하고 변경할 때이 문제에 대해 무엇을 할 수 있습니까? 일반적인 해결책은 반대로 작업하는 것입니다. ES3를 사용 하면서 하지만 당신은 사용할 수 에 대한 선호 경우 설탕

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a' ,'a', 'b', 'c', 'b', 'a', 'a'],
  index = review.length - 1;

while (index >= 0) {
  if (review[index] === 'a') {
    review.splice(index, 1);
  }

  index -= 1;
}

log(review);
<pre id="out"></pre>

좋아,하지만 ES5 반복 방법을 사용하고 싶었습니다. 글쎄 그리고 옵션은 Array.prototype.filter 를 사용하는 것이지만 이것은 원래 배열을 변경하지 않지만 새 배열을 생성하므로 정답을 얻을 수 있지만 지정한 것처럼 보이지 않습니다.

우리는 또한 ES5 Array.prototype.reduceRight를 사용할 수 있습니다. 오히려 반복 속성에 의한 감소 속성이 아니라 역으로 반복합니다.

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.reduceRight(function(acc, item, index, object) {
  if (item === 'a') {
    object.splice(index, 1);
  }
}, []);

log(review);
<pre id="out"></pre>

또는 ES5 Array.protoype.indexOf를 그렇게 사용할 수 있습니다 .

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'],
  index = review.indexOf('a');

while (index !== -1) {
  review.splice(index, 1);
  index = review.indexOf('a');
}

log(review);
<pre id="out"></pre>

하지만 특별히 ES5 Array.prototype.forEach 를 사용하고 싶다면 어떻게해야할까요? 배열과 Array.prototype.reverse 의 얕은 복사본을 만들기 위해 Array.prototype.slice 를 사용해야 합니다. 그러면 원래 배열을 변경하기 위해 반대로 작업 할 수 있습니다.

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.slice().reverse().forEach(function(item, index, object) {
  if (item === 'a') {
    review.splice(object.length - 1 - index, 1);
  }
});

log(review);
<pre id="out"></pre>

마지막으로 ES6는 얕은 복사본을 만들고 뒤집을 필요가없는 몇 가지 추가 대안을 제공합니다. 특히 우리는 Generators와 Iterators를 사용할 수 있습니다 . 그러나 현재 지원은 상당히 낮습니다.

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

function* reverseKeys(arr) {
  var key = arr.length - 1;

  while (key >= 0) {
    yield key;
    key -= 1;
  }
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

for (var index of reverseKeys(review)) {
  if (review[index] === 'a') {
    review.splice(index, 1);
  }
}

log(review);
<pre id="out"></pre>

위의 모든 것에서 주목할 점 은 배열에서 NaN 을 제거하는 경우 Javascript NaN === NaN에서 거짓 이기 때문에 같음과 비교하는 것이 작동하지 않는다는 것 입니다. 그러나 우리는 아직 명시되지 않은 또 다른 엣지 케이스이므로 솔루션에서 그것을 무시할 것입니다.

그래서 우리는 여전히 엣지 케이스가있는 솔루션으로 더 완전한 답을 얻었습니다. 첫 번째 코드 예제는 여전히 정확하지만 언급했듯이 문제가없는 것은 아닙니다.


답변

Array.prototype.filter대신 사용 forEach:

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'b', 'c', 'b', 'a', 'e'];
review = review.filter(item => item !== 'a');
log(review);


답변

Xotic750의 답변 은 몇 가지 좋은 점과 가능한 솔루션을 제공 하지만 때로는 간단한 것이 더 좋습니다 .

반복되는 배열이 반복 자체에서 변경된다는 것을 알고 있습니다 (즉, 항목 제거 => 인덱스 변경). 따라서 가장 간단한 논리는 구식 for( C 언어) 에서 뒤로 이동하는 것입니다 .

let arr = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

for (let i = arr.length - 1; i >= 0; i--) {
  if (arr[i] === 'a') {
    arr.splice(i, 1);
  }
}

document.body.append(arr.join());

당신이 그것에 대해 정말로 생각한다면, a forEachfor루프를 위한 문법적 설탕 일뿐입니다 … 그래서 그것이 당신을 돕지 않는다면, 그것에 대해 머리를 부수 지 마십시오.


답변

대신 indexOf를 사용하여이 작업을 수행 할 수도 있습니다.

var i = review.indexOf('\u2022 \u2022 \u2022');
if (i !== -1) review.splice(i,1);


답변

조건을 사용하여 배열에서 제거하고 배열에서 항목이 제거 된 다른 배열을 원한다는 것을 이해했습니다. 맞습니까?

이건 어때요?

var review = ['a', 'b', 'c', 'ab', 'bc'];
var filtered = [];
for(var i=0; i < review.length;) {
  if(review[i].charAt(0) == 'a') {
    filtered.push(review.splice(i,1)[0]);
  }else{
    i++;
  }
}

console.log("review", review);
console.log("filtered", filtered);

이 도움을 바랍니다 …

그건 그렇고, 나는 ‘for-loop’와 ‘forEach’를 비교했습니다.

문자열에 ‘f’가 포함 된 경우 제거하면 결과가 다릅니다.

var review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
var filtered = [];
for(var i=0; i < review.length;) {
  if( review[i].includes('f')) {
    filtered.push(review.splice(i,1)[0]);
  }else {
    i++;
  }
}
console.log("review", review);
console.log("filtered", filtered);
/**
 * review [  "concat",  "copyWithin",  "entries",  "every",  "includes",  "join",  "keys",  "map",  "pop",  "push",  "reduce",  "reduceRight",  "reverse",  "slice",  "some",  "sort",  "splice",  "toLocaleString",  "toSource",  "toString",  "values"]
 */

console.log("========================================================");
review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
filtered = [];

review.forEach(function(item,i, object) {
  if( item.includes('f')) {
    filtered.push(object.splice(i,1)[0]);
  }
});

console.log("-----------------------------------------");
console.log("review", review);
console.log("filtered", filtered);

/**
 * review [  "concat",  "copyWithin",  "entries",  "every",  "filter",  "findIndex",  "flatten",  "includes",  "join",  "keys",  "map",  "pop",  "push",  "reduce",  "reduceRight",  "reverse",  "slice",  "some",  "sort",  "splice",  "toLocaleString",  "toSource",  "toString",  "values"]
 */

그리고 각 반복마다 제거하면 결과도 다릅니다.

var review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
var filtered = [];
for(var i=0; i < review.length;) {
  filtered.push(review.splice(i,1)[0]);
}
console.log("review", review);
console.log("filtered", filtered);
console.log("========================================================");
review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
filtered = [];

review.forEach(function(item,i, object) {
  filtered.push(object.splice(i,1)[0]);
});

console.log("-----------------------------------------");
console.log("review", review);
console.log("filtered", filtered);


답변

다음은 특수 캐릭터와 동일하지 않은 모든 요소를 ​​제공합니다!

review = jQuery.grep( review, function ( value ) {
    return ( value !== '\u2022 \u2022 \u2022' );
} );


답변

방법은 다음과 같습니다.

review.forEach(function(p,index,object){
   if(review[index] === '\u2022 \u2022 \u2022'){
      console.log('YippeeeE!!!!!!!!!!!!!!!!')
      review.splice(index, 1);
   }
});