Developer/자바스크립트

자바스크립트 , Array 순회 메서드

단님 2024. 6. 4. 19:42
728x90

 

 

map(요소 , 인덱스 , 배열전체) 순회 메서드→ 원본 안바뀜

 

주어진 배열의 값을 재정의 할 때 사용하는 방법

ECMA에는 "주어진 배열의 값들을 인덱스의 오름차순으로 접근해 callbackfn을 통해

새로운 값을 정의하고 신규 배열을 만들어 반환한다"라고 정의됨.

배열을 순회하면서 공통된 작업을 할때, 사용함.

map 의 인자를 콜백함수를 통해 함수를 넣어줌.

인자로 사용되어지는 함수를 콜백함수라고 함.(1급함수라고 함.)

객체의 메서드는 인자가 될수 없고 1급함수가 아님.

자바스크립트는 함수를 많이쓰기에 함수형 언어다 라고 볼 수 있다.

 

        document.write("** 원본 money=> " + money + "<br>");
        result = money.map(m=> m+ m*0.1);
        document.write("** money.map(m=> m+ m*0.1)=> " + result + "<br>");
        document.write("** map후 원본 money=> " + money + "<br>");
        document.write("<br>");

 

map 은 아주많이 사용할 것이다.

원본 데이터를 변경한 것은 아니다.

다만 , 받아서 새로운 값을 받은 다른 변수에 새로운 배열을 만들었다.

* 콜백 함수

        //=> callbackfn 의 인자값
        //  m: 요소의 값
        //  i: index
        //  s: 순회하는 대상 
        result = money.map((m, i, s) => {
            document.write(`m=${m}, i=${i}, s=${s}<br>`);
            return m * m;
        });
        document.write("** result map(m,i,s) => " + result + "<br>");

 

i라고해서 인덱스가 아니라 두번째 위치했기에 인덱스 값이 나옴.

i는 매개 변수 일 뿐이야 !

(첫번째 위치 , 두번째 위치 , 세번째 위치)

(요소 값 , 인덱스 , 순회대상의 배열)

 

*화살표 함수

인자가 하나라면 소괄호를 생략할수 있음.

리턴문이 있는 콜백함수라면 , 중괄호를 사용해야함.

리턴문이 없는 콜백함수라면 , 중괄호를 생략할 수 있다.

실행문이 있으 return 이 생략된다.

 

중간에 접근된 수정된 정보에 대해서는 map 이 접근할 수 없다.

-> push . pop

//   map 의 CallBack 함수내에서 추가된 Data 에는 접근하지않음
        result = money.map(m => {
            money.push(123);
            // => 배열에 데이터 요소 추가함.
            return m * m;
        });
        document.write("** result push 적용 => " + result + "<br>"); //push 가 반영되지 않음.
        document.write("** money push 적용 => " + money + "<br>"); //원본데이터에 대해 push.

        result = money.map(m => {
            money.pop();
            // => 배열에 데이터 요소 삭제함 : 적용됨
            return m * m;
        });
        document.write("** result pop 적용 => " + result + "<br>");
        document.write("** money pop 적용 => " + money + "<br>");

        document.write("<br>");

 

filter(callbackFn, thisArg)) 참인 애들을 새배열로 구성

배열의 각 요소에 대해 제공된 callbackFn 함수를 한 번씩 호출하고,

callbackFn이 참 값을 반환하는 모든 값으로 새 배열을 구성

callbackFn 테스트를 통과하지 못한 배열 요소는 새 배열에 포함되지 않음

테스트를 통과한 요소가 없으면 빈 배열이 반환됨.

두번째인자 thisArg : callbackFn을 실행할 때 this로 사용할 값

보통 외부의 함수(필터링 하고싶은 조건)를 불러들여 filter 를 사용함.

        words = ["JavaScript", "짜장면", "SpringBoot", "987654", "Banana"];

        function isBig(value){
            if (value.length>=5) {
                return value;
            }
        }
        result = words.filter(isBig);
        document.write("** result적용 => " + result + "<br>");

 

reduce(callbackFn, initValue) 함수 결과값을 반환

 

배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환

 

        let initValue = 100;
        document.write("** initValue 초기 값 => " + initValue + "<br>");
        document.write("** money 초기 값 => " + money + "<br>");
        result = money.reduce(
            (a, c)=>{
                document.write(`a = ${a} , c = ${c}<br>`)
                return a + c;
            },initValue); //100에서 시작하여 값이 누적됨.
            document.write("** money.reduce a+c => " + result + "<br>");

초기값 부터 c로 각 money의 배열 요소들을 더하게 되어 ,

최종적으로 누적값을 구할 수 있음.

콜백함수를 통해 배열 전체 연산 결과 값을 구할 수 있음.

최종값은 마지막에 하나가 나옴을 알 수 있다.

객체속 객체 접근일 땐 초기값을 생략하면 ,안됨. 0이라도 넣자. 그냥 넣자.

 

배열속 객체접근.

let sumObj = [{ x: 1, y: 10 }, { x: 2, y: 20 }, { x: 3, y: 30 }]
        
        document.write("** sumObj 초기 값 => " + sumObj + "<br>");
        
        sumObj = [{ x: 1, y: 10 }, { x: 2, y: 20 }, { x: 3, y: 30 }].reduce(
            (acc,curr) => acc+curr.x+curr.y,initValue);
        document.write("** acc+curr.x+curr.y => " + sumObj + "<br>");
        document.write("<br>");
        
        sumObj = [{ x: 1, y: 10 }, { x: 2, y: 20 }, { x: 3, y: 30 }].reduce(
            (acc,curr) => acc+curr.x+curr.y,0);
        document.write("** acc+curr.x+curr.y => " + sumObj + "<br>");
        document.write("<br>");

 

find(callbackFn, thisArg) 요소를 찾자

allbackFn 이 참 값을 반환할 때까지 배열을 인덱스 오름차순으로 순회하며,

반환값이 결정되면 순회를 중지하고 find() 는 해당 요소를 반환함.

callbackFn 이 참 값을 반환하지 못하면 find() 는 undefined 를 반환함.

배열의 length는 callbackFn을 처음 호출하기 전에 저장되므로,

callbackFn은 배열의 초기 length 값을 초과하여 도중에 추가된 요소는 방문하지 않음.

이미 방문한 인덱스를 변경해도 callbackFn은 해당 인덱스에 대해 재호출하지 않음.

아직 방문하지 않은 요소가 callbackFn에 의해 변경되는 경우 callbackFn에 전달되는 값은

해당 요소가 방문될 당시의 값이 됨. 삭제된 (en-US) 요소는 undefined가 있는것 처럼 방문됨.

 

        const inventory = [
            { name: "apples", quantity: 2 },
            { name: "bananas", quantity: 0 },
            { name: "cherries", quantity: 5 },
        ];
        document.write("** inventory => " + inventory + "<br>");
        document.write("<br>");
        
        result = inventory.find(({name}) => name === "apples");
        document.write("** result => { name: " + result.name + ", quantity: " + result.quantity + " }<br>");
        document.write("<br>");

 

forEach(callbackFn, thisArg)

 

주어진 콜백함수를 실행하기만 함.

체이닝으로 연결이 불가능 함.

배열을 반복문 처럼 사용하기 때문에 사용빈도수가 높음.

배열의 각 요소에 대해 제공된 callbackFn 함수를 오름차순 인덱스 순서로 한 번씩 호출 callbackFn은 값이 할당된 배열 인덱스에 대해서만 호출 항상 undefined를 반환하므로 체이닝 불가함 (map()과 차이점)

~.map(...).reduce(...).forEach(....)

맵은 다시 배열을 반환하지만

forEach는 반환하지 않고 실행에 대한 호출만 되는 상황임.

 

        words = ["JavaScript", "짜장면", "SpringBoot", "987654", "Banana"];
        document.write("** words 원본 => " + words + "<br>");

        document.write("<br>");

        result = words.map(m => m.length);
        document.write("** words.map 적용 => " + result + "<br>");
        document.write("<br>")
        
        result = words.forEach(m => {
        document.write(`${m} = ${m.length} <br>`)});
        document.write("<br>");

        document.write("** words.forEach 적용 => " + result + "<br>");
        document.write("<br>");

map 같은경우 배열을 반환하지만 , forEach 는 배열을 반환하지 않기때문에 , 체이닝 적용이 불가.

 

메서드 체이닝
        //메서드 체이닝
        numbers = [300 , 100 , 200 , 50 , 0 , 7 , 22];

        function add(a) {
            return a+5;
        };
        function filter(a){
            if(a>50){
                return a;
            }
        }
        
        numbers.map(add).filter(filter).forEach(
            (m, i) => document.write(`${m}은 인덱스 ${i} <br>`)
        );
        document.write("<br>");
        document.write("** numbers 원본 => " + numbers + "<br>");
        document.write("** numbers.map (+1) => " + numbers.map(add) + "<br>");
        document.write("** numbers.map.filter (+1)(50이상) => " + numbers.map(add).filter(filter) + "<br>");

어떤값을 리턴하는냐를 알아야 체이닝을 이용할 수 있다.

배열은 어떠한 데이터를 담아 놓는 형식.

자료들을 보관하는 목적으로 설계한 객체를 컬렉션이라고 함.