코드 스터디

JS 배열 메서드『map() │ forEach()』

Recstasy 2021. 5. 2. 11:48

for, if구문이 꼬리에 꼬리를 물고 있는 코드는 작업시간을 잡아먹는 괴물이다.

for 혹은 if구문이 난잡하게 널려있는 코드를 보면 정신이 혼란하다.

 

결론적으로 for구문을 될 수 있는 한 사용하지 않고,

배열메서드를 사용하는 편이 클린코드에 가깝다.

(자료구조에 따라 for..of, for...in문이 효율적일 수 있음)

 

 

* fruits배열에서 '폰' 데이터는 몇개인가?

 

let fruits = ['사과', '오렌지', '사과폰', '바나나', '딸기', '바나나폰', '파인애플', '수박', '오렌지폰']

 

위와같은 문제를 풀기위해 for구문을 사용한다면

아래와 같이 for문 내에서 if조건문을 사용하는 방법을 생각할 수 있다.

 

for(let i=0; i<fruits.length; i++){

	if(fruits[i].match(/폰/)){
		  console.log('폰:'+fruits[i]);
    }

}

 

그런데

만일 fruits데이터의 내부값이 객체라면 어떨까?

 

let fruits = [
	{
    	name:'사과',
    	state:'특상',
        price:'2,000원'
    }, 
    {
    	name:'오렌지'
    	state:'중하',
        price:'1,500원'
    }, 
    {
    	name:'사과폰pro10'
    	state:'중고',
        price:'1100000원'
    }, 
    {
    	name:'바나나'
        state:'상급',
        price:'800원'
    }, 
    {
    	name:'딸기'
        state:'중급',
        price:'400원'
    }, 
    {
    	name:'바나나폰'
        state:'신동품',
        price:'50000원'
    }, 
    {	
    	name:'파인애플'
        state:'하급',
        price:'2000원'
    }, 
    {
    	name:'수박'
        state:'중상급',
        price:'6000원'
    }, 
    {
    	name:'오렌지폰'
        state:'중급',
        price:'10000원'
    }
];

 

for구문이 3개 이상 중첩되기 시작하고, 그 사이에 조건문까지 개입되면

아래와 같이 점차 알아보기 힘든 코드가 된다.

 

for(let i=0; i<fruits.length; i++){

	for(let item in fruits[i]){
    
		for(let j=0; j<item.length; j++){
        
			if(item[j].value.match(/폰/){
				console.log('폰입니다');
			}else{
				return item[j].value;
                
			}
            
		}
        
	}
    
}                  

 

위와같은 상황에서 필요한 도구가 '배열메서드'이다.

배열 메서드는 스파게티 코드가 되어가는 상황을 풀어줄 수 있는 훌륭한 도구다. 

 

 

 

│Map( )

map() = 새로운 배열 생성

map(), forEach()메서드의 가장 큰 차이점은 '반환값' 유무이다.

map()의 경우, 데이터에서 필요한 값을 새로운 배열 형태로 반환할 수 있다.

 

map()을 사용하기 좋은 케이스는

기존의 속성을 뽑아내어 새로운 유형(전기차=새로운 배열)을 생성하는 것과 비슷하다.

 

 

│forEach( )

forEach() => 기존 데이터 수정

forEach()메서드는 반환값이 없다.

원본 배열의 개별값을 하나씩 수정하는 방식이며,

기존의 데이터를 통해 뭔가 새로운 형태를 만들어내기보다

기존의 것을 튜닝하는 상황에 적합하다.

 

 

 

 

│결과

위의 fruits데이터를 map(), forEach()구문으로 정리하면 아래와 같다.

 

//fruits1, fruits2는 fruits 데이터와 같음

		console.log('================map=================')
        let res1 = fruits1.map((fruit1)=>{ return fruit1.name='참외'; });
            res1.push({name:'감',state:'중급',price:'4000원'});
        console.log(fruits1);
        console.log(res1);

       

        console.log('================forEach=================')
        let res2 = fruits2.forEach((fruit2)=>{ fruit2.name ='참외' });
            //forEach()구문은 추가 불가 **// res2.push({name='감',state:'중급',price:'4000원'});
        console.log(fruits2);
        console.log(res2);

 

map()메서드의 경우, 새로운 배열이 생성되면서 '감'객체가 추가되었고,

forEach()의 경우, 새로운 배열이 없으므로 'undefined'가 출력된다. 

 

 

새 배열의 생성유무는 상당히 중요한데,

다음과 같이 코드의 직관성(체이닝)이 달라지기 때문이다.

 

let res1 = fruits1.map(fruit=>fruit)
                  .filter(item=>(item.name ==='오렌지폰') ? item : false)

console.log(res1);

 

결론적으로,

for구문을 사용할 수밖에 없는 상황이 아닌 이상,

코드를 읽는 팀원들을 배려한다는 기준에서

배열 메서드를 사용하는 편이 좋다.