javascript array 중복 - 각 배열에 대한 자바 스크립트?





14 Answers

편집 :이 답변은 절망적으로 오래되었습니다. 보다 근대적 인 접근법을 얻으 려면 어레이에서 사용할 수있는 방법을 살펴보십시오. 관심 대상의 방법은 다음과 같습니다.

  • 각각
  • 지도
  • 필터
  • 지퍼
  • 줄이다
  • ...마다
  • 약간

JavaScript 에서 배열을 반복하는 표준 방법 for -loop의 바닐라 for .

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

그러나이 방법은 조밀 한 배열이 있고 각 인덱스가 요소로 채워져있는 경우에만 유용합니다. 배열이 희소 한 경우 배열에 실제로 존재하지 않는 많은 인덱스를 반복하므로이 접근 방식으로 성능 문제가 발생할 수 있습니다. 이 경우 for..lo-loop이 더 좋은 아이디어 일 수 있습니다. 그러나 for..in -loop도 레거시 브라우저에서 열거되거나 추가 (예 : 배열 요소)가 필요하면 적절한 보호 책을 사용해야 어레이의 원하는 속성 (즉, 배열 요소) 만 작동하도록해야합니다. 속성은 enumerable 정의됩니다.

ECMAScript 5 에서는 배열 프로토 타입에 forEach 메서드가 있지만 레거시 브라우저에서는 지원되지 않습니다. 따라서 일관되게 사용할 수 있으려면이를 지원하는 환경 (예 : 서버 측 JavaScript의 경우 Node.js )이 있거나 "Polyfill"을 사용해야합니다. 그러나이 기능을위한 Polyfill은 간단하며 코드를 읽기 쉽게 만들어주기 때문에 포함시킬 좋은 polyfill입니다.

개수 비교 배열과

JavaScript를 사용하여 배열의 모든 항목을 반복하는 방법은 무엇입니까?

나는 그것이 다음과 같다고 생각했다.

forEach(instance in theArray)

어디에 theArray 내 배열이지만 잘못된 것으로 보입니다.




뒤로 루프

역방향 for 루프는 여기에 언급 할 가치가 있다고 생각합니다.

for (var i = array.length; i--; ) {
     // process array[i]
}

장점 :

  • 임시 len 변수를 선언하거나 각 반복에서 array.length 와 비교할 필요가 없습니다.이 중 하나는 미세 최적화 일 수 있습니다.
  • DOM에서 형제 를 역순으로 제거하는 것이 일반적으로 더 효율적 입니다. (브라우저는 내부 배열의 요소 이동이 적어야합니다.)
  • 루프하면서, 인덱스 i 에서 또는 후에 배열수정하면 (예 : array[i] 에서 항목을 제거하거나 삽입하면) 앞으로 루프는 왼쪽으로 이동 한 항목을 건너 뜁니다. 또는 i 를 다시 처리합니다 오른쪽으로 이동 한 항목. 전통적인 for 루프에서는 처리가 필요한 다음 항목 ( 1) 을 가리 키도록 i 를 업데이트 할 있지만 간단히 반복의 방향을 바꾸는 것이 종종 더 간단 하고 우아한 해결책 입니다.
  • 마찬가지로, 중첩 된 DOM 요소를 수정하거나 제거 할 때 역순으로 처리하면 오류피할 수 있습니다 . 예를 들어, 자식을 처리하기 전에 부모 노드의 innerHTML을 수정하는 것을 고려하십시오. 자식 노드에 도달 할 때까지 DOM에서 분리되어 부모의 innerHTML이 작성되면 새로 생성 된 자식으로 대체됩니다.
  • 사용할 수있는 다른 옵션 중 일부를 입력하고 읽는 것이 더 짧 습니다. 그것은 forEach() 와 ES6 forEach() for ... of 잃는다.

단점 :

  • 항목을 역순으로 처리합니다. 결과에서 새 배열을 만들거나 화면에 내용을 인쇄하는 경우 자연스럽게 원래 순서대로 출력이 반전 됩니다.
  • 순서를 유지하기 위해 형제를 첫 번째 자식으로 DOM에 반복적으로 삽입하는 것은 덜 효율적 입니다. DOM 노드를 효율적이고 순차적으로 생성하려면 보통 전달 및 추가 (그리고 "문서 조각"사용)하기 만하면됩니다.
  • 후진 루프는 중학교 개발자들에게 혼란 스럽 습니다. (귀하의 전망에 따라 이점을 고려할 수도 있습니다.)

나는 항상 그것을 사용해야합니까?

일부 개발자는 앞으로 전달할 좋은 이유가없는 한 기본적으로 reverse for 루프 사용합니다.

성능 향상은 대개 중요하지 않지만 다음과 같이 비명을 지릅니다.

"목록의 모든 항목에이 작업을 수행하면 주문에 신경 쓰지 않습니다!"

그러나 실제로는 의도에 대한 신뢰할 수있는 표시가 아니며 주문에 대해 신경 쓰는 경우와 구분할 수 없으므로 실제로 역순으로 반복 해야 합니다. ECMAScript를 비롯하여 대부분의 언어에서는 현재 사용할 수 없지만 예를 들어 forEachUnordered() 와 같이 호출 할 수있는 "무효"의도를 정확하게 표현하려면 다른 구문이 필요합니다.

순서가 중요하지 않고 효율성 (게임이나 애니메이션 엔진의 가장 안쪽 루프에서)이 중요하다면 reverse for 루프를 이동 패턴으로 사용하는 것이 허용 될 수 있습니다. 기존 코드에서 reverse for 루프를 본다고해서 순서가 관련성 이 없다는 것을 반드시 기억 하지 마십시오 !

forEach ()를 사용하는 것이 더 좋습니다.

일반적으로 선명도와 안전성 이 더 중요한 고차원 코드의 경우 기본 패턴으로 Array::forEach 를 사용하는 것이 좋습니다.

  • 읽을 것이 분명합니다.
  • 그것은 블록 내에서 이동하지 않을 것임을 나타냅니다 (항상 forwhile 루프에 숨어있을 가능성이 있습니다).
  • 그것은 당신에게 종결을위한 무료 범위를 제공합니다.
  • 그것은 국소 변수의 누설과 외부 변수의 우발적 인 충돌 (및 돌연변이)을 줄입니다.

그런 다음 코드에서 reverse for 루프를 볼 때, 이는 좋은 이유 (아마도 위에 설명 된 이유 중 하나 일 수 있음)가 바뀌 었다는 힌트입니다. 그리고 전통적인 for for loop를 보면 이동이 발생할 수 있음을 나타낼 수 있습니다.

(의도에 대한 토론이 당신에게 이해가되지 않는다면, 프로그래밍 스타일과 두뇌 에 관한 Crockford의 강연을 보면서 당신과 당신의 코드가 도움이 될 것입니다.)

어떻게 작동합니까?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

중간 절 (우리가 보통 비교를 보는 곳)과 마지막 절이 비어 있음을 알 수 있습니다 (여기서 우리는 보통 i++ 보았습니다). 즉, i-- 또한 계속을위한 조건 으로 사용된다는 것을 의미합니다. 결정적으로 각 반복 전에 실행되고 검사됩니다.

  • 폭발하지 않고 array.length 에서 어떻게 시작할 수 있습니까?

    왜냐하면 각 반복 전에 먼저 실행 되기 때문에 첫 번째 반복에서 array-out-of-bounds undefined 항목 문제를 피하는 array.length - 1 의 항목에 실제로 액세스하게됩니다.

  • 인덱스 0 이전에 iterating이 중지되지 않는 이유는 무엇입니까?

    루프는 조건 i-- 가 거짓 값으로 평가 될 때 반복을 중지합니다 (0을 산출 할 때).

    트릭은 --i 와 달리 후행 i 연산자는 i 감소 i-- 감소 이전 의 값을 산출합니다. 콘솔에서 다음을 입증 할 수 있습니다.

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    따라서 최종 반복에서 나는 이전에 1 이었고 i - expression은 0으로 변경했지만 실제로는 1 (truthy)을 산출하므로 조건이 통과됩니다. 다음 반복에서 i-1을 i 로 변경하지만 0 (거짓)을 생성하므로 실행이 즉시 루프 맨 아래로 빠져 나갑니다.

    전통적인 Forward for for 루프에서 ++++ ++i 는 서로 교환 가능합니다 (Douglas Crockford가 지적했듯이). 그러나 reverse for 루프에서는 감소 값이 조건 식이 i-- 인덱스 0에서 항목을 처리하려면 i-- 사용해야합니다.

하찮은 일

어떤 사람들 for 루프의 반대쪽 for 작은 화살표를 그리고 윙크로 끝내기를 좋아합니다.

for (var i = array.length; i --> 0 ;) {

크레딧은 WYL에서 reverse for 루프의 이점과 공포를 보여주기 위해 사용됩니다.




배열을 반복하려면 표준 3 부분 for 루프를 사용하십시오.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

myArray.length 를 캐싱하거나 역순으로 반복하여 성능 최적화를 얻을 수 있습니다.




배열을 비우는 것에 신경 쓰지 않는다면 :

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

xy 의 마지막 값을 포함하며 배열에서 제거됩니다. shift() 를 사용하여 y 에서 첫 번째 항목을주고 제거 할 수도 있습니다.




쉬운 해결책은 이제 underscore.js 라이브러리 를 사용하는 것 입니다. 이 도구는 다음과 같은 유용한 도구를 제공 each하며 작업이 forEach가능한 경우 해당 작업을 자동으로 위임합니다 .

CodePen 의 작동 원리 는 다음과 같습니다.

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

또한보십시오

  • Array::forEach .
  • 에서 for_each...in (MDN)는 그 설명 for each (variable in object)ECMA-357 (의 일부로서 사용되지 EAX ) 표준.
  • for...of (MDN) for (variable of object)은 Harmony (ECMAScript 6) 제안의 일부로 사용하는 다음 반복 방법을 설명합니다 .



세 가지 구현이 있습니다 foreach에서 jQuery 다음과 같이가.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3



for each네이티브 JavaScript 에는 루프 가 없습니다 . 라이브러리를 사용하여이 기능을 사용할 수 있습니다 (나는 Underscore.js 권장합니다 ) for. 간단한 루프를 사용하십시오.

for (var instance in objects) {
   ...
}

그러나 더 단순한 for루프 를 사용하는 이유가있을 수 있습니다 (스택 오버플로 질문 참조). 왜 "for ... in"을 배열 반복과 함께 사용하는 것이 좋지 않은가? )

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}



있다 몇 가지 방법 루프는 다음과 자바 스크립트의 배열을 통해 :

왜냐하면 가장 일반적인 것이기 때문입니다. 루핑을위한 전체 코드 블록

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

while - 조건이 끝나는 동안 루프. 가장 빠른 루프 인 것 같습니다.

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do / while - 조건이 참일 때 코드 블록을 반복하면서 적어도 한 번 실행됩니다.

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

기능 루프 - forEach, map, filter, 또한 reduce(그들은 기능을 통해 루프,하지만 당신은 등 배열, 뭔가를해야 할 경우에 사용

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

배열에 대한 함수 프로그래밍에 대한 자세한 내용과 예제는 블로그 게시물 Functional programming in JavaScript : map, filter and reduce를 참조하십시오 .




배열로 작업하는 ECMAScript5 (Javascript의 버전).

forEach - 배열의 모든 항목을 반복하고 각 항목에 필요한 모든 작업을 수행합니다.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

경우에, 더 inbuilt 기능을 사용하여 배열 작업에 관심이 많습니다.

map - 콜백 함수의 결과로 새로운 배열을 생성합니다. 이 방법은 배열의 요소를 형식화해야 할 때 사용하는 것이 좋습니다.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

reduce - 이름에서 알 있듯이 currenct 요소에서 전달 된 주어진 함수와 이전 실행 결과를 호출하여 배열을 단일 값으로 줄입니다.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - 배열의 모든 요소가 콜백 함수에서 테스트를 통과하면 true 또는 false를 반환합니다.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

filter - 필터가 해당 함수에 true를 반환하는 요소가있는 배열을 반환한다는 점을 제외하고는 모두 매우 비슷합니다.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

희망이 유용 할 것입니다.




jQuery 방식을 사용하여 $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];



람다 구문은 일반적으로 IE 10 이하에서 작동하지 않습니다.

나는 보통

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});



forEach는 다음과 같이 호출 할 수 있습니다.

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

요소는 0부터 배열의 길이까지의 각 인덱스의 값을가집니다.

산출:

1    
3    
2

설명 :

forEach는 프로토 타입 클래스입니다. 당신은 또한 thisArray.prototype.forEach (...);

프로토 타입 : https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

다음과 같이 배열을 변경할 수도 있습니다.

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}



당신이 사용하고 싶다면 forEach(), 그것은 -

theArray.forEach ( element => { console.log(element); });

당신이 사용하고 싶다면 for(), 그것은 -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }




개요:

배열을 반복 할 때 종종 다음 목표 중 하나를 달성 할 수 있습니다.

  1. 우리는 배열을 반복하고 새로운 배열을 생성하고자합니다 :

    Array.prototype.map

  2. 우리는 배열을 반복하고 새로운 배열을 만들지 않기를 원합니다 :

    Array.prototype.forEach

    for..of 고리

JS에서는 이러한 두 가지 목표를 달성하는 여러 가지 방법이 있습니다. 그러나 어떤 것은 다른 것보다 conventient하다. 아래에서 자바 스크립트에서 배열 반복을 수행하기 위해 일반적으로 사용되는 메소드 (가장 conventient imo)를 찾을 수 있습니다.

새 배열 만들기 : Map

map()Array.prototype배열의 모든 요소를 ​​변형 할 수 있는 함수 이며 배열 을 반환합니다 . map()인수로 콜백 함수를 사용하며 다음과 같은 방식으로 작동합니다.

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

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

map()인수로 전달한 콜백 은 모든 요소에 대해 실행됩니다. 그런 다음 원래 배열과 길이가 같은 배열이 반환됩니다. 이 새로운 배열 요소는 인수로 전달 된 콜백 함수에 의해 변형됩니다 map().

사이에 뚜렷한 차이 map와 같은 다른 루프 메커니즘 forEachfor..of루프가있는 map새로운 배열로 반환 그대로 기존의 배열을 잎 (같은 생각에 당신이 명시 적으로이를 조작하는 경우를 제외하고 splice).

또한이 map함수의 콜백은 현재 반복의 인덱스 번호를 두 번째 인수로 제공합니다. 또한 세 번째 인수 map는 호출 된 배열을 제공합니다 . 때로는 이러한 속성이 매우 유용 할 수 있습니다.

루프 사용 forEach

forEach에있는 함수 Array.prototype의 인수로 콜백 함수가 걸린다. 그런 다음 배열의 모든 요소에 대해이 콜백 함수를 실행합니다. map()함수 와 달리 forEach 함수는 nothing ( undefined)을 반환합니다 . 예 :

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

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

그냥 같은 map기능의 forEach콜백은 두 번째 인수로 현재 반복의 인덱스 번호를 제공합니다. 또한 세 번째 인수 forEach는 호출 된 배열을 제공합니다 .

요소를 통해 반복 사용 for..of

for..of루프는 배열 (또는 다른 반복 가능한 객체)의 모든 요소를 통해 루프. 그것은 다음과 같은 방식으로 작동합니다 :

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

for(let element of arr) {
  console.log(element * 2);
}

위의 예에서는 element배열 요소 를 나타내며 arr루프를 만들려는 배열입니다. 이름 element이 임의적 인 것은 아니며 'el'또는 이와 유사한 다른 선언문을 적용 할 수 있습니다.

for..in루프를 루프와 혼동하지 마십시오 for..of. for..in배열의 모든 열거 가능 속성을 for..of반복합니다. 반면 루프는 배열 요소를 반복합니다. 예 :

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

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}




Related