FrontEnd/Javascript

[JavaScript] 배열 메소드 map, filter 개념 및 예시 (배열 내 특정 조건에 해당하는 데이터 가져오는 방법)

김평범님 2020. 12. 3. 20:00
반응형

JavaScript의 Array 메서드 중 강력한 기능

Map, filter  활용하기


JavaScript 배열메소드 map, filter 사용하기

최근 프로젝트 개발 중 DBQuery를 통해 받은 결과를 재가공하는 일이 많아졌다.

해당 값에서 중복을 제거한다던지, 특정 조건을 만족하는 값으로 새로운 배열을 만들어야 할 경우가 생겼는데,

이 경우 많은 선배 개발자들은 Array 메서드인 map과 filter를 활용하는 것을 알 수 있었다.

 

 

오늘은 이러한 Array에서 Map과 Filter가 무엇인지, 어떤 식으로 이용해야 될지 공부를 해보기로 했다.

💎Array.prototype.map()

ES5에서는 Array method 중 Map이 추가되었다.

map()을 활용할 경우, 특정 배열을 for문을 도는 것처럼 각각의 요소에 대해

함수를 호출하여, 해당 함수를 실행한 뒤 새로운 형태의 배열을 얻을 수 있다.

 

이때, 기존에 호출된 배열은 변하지 않고 원본을 유지하며,

새로운 결과 데이터로 새로운 배열을 만들 수 있게 된다.

 

 

//원본 배열 생성
const testArray = [1,2,3,4];

//map을 이용하여, 원본배열에 * 2 곱한 새로운 배열 생성
//매개변수 x를 console log로 찍어보면, 
//for문을 돌면서 배열의 값을 하나 씩 가져오는걸 확인할 수 있다.

const ResultMap = testArray.map(x=> {
	console.log(x);
	return x*2;
});

//map으로 원본배열에 * 2를 곱한 새로운 배열 생성
console.log(ResultMap);

//map과 상관없이 기존 배열은 동일한 값 유지 
console.log(testArray);

코드 결과 화면

코드의 간결성

물론 위의 식은 기존 for문을 통해서도 만들 수 있지만,

기존에 4줄로 했던 식을 한 줄로 작성할 수 있어 가독성이 좋아지는 장점이 있다.

 

//원본 배열 생성
const testArray = [1,2,3,4];

//기존 for문 방식
const forResult =[];
for(let i = 0; i <testArray.length; i+=1) {
    forResult.push(testArray[i] * 2);
}
console.log(forResult);

//맵을 활용한 방식
const ResultMap = testArray.map((x)=> {return x * 2})

console.log(ResultMap);

코드 결과 화면


👀 Map의 문법 살펴보기

map 기본 사용 문법

기본 문법은 원본 Array에서 map을 이용해 callback 함수를 실행하는 방식으로 사용한다.

 

array.map((currentValue, index, array) => {});

 

매개변수

map의 callback 함수는  총 3가지의 매개변수를 가지고 있다.

  • CurrentValue :  현재 처리하고 있는 원본 배열의 데이터
  • index :  현재 처리 중인 인덱스
  • array :  현재 map() 메서드를 실행하고 있는 원본 배열

 

const testArray = [1,2,3,4];

const ResultMap = testArray.map((i,x,z)=> {
console.log("현재 처리중인 원본데이터: " + i);
console.log("현재 처리중인 인덱스: " + x);
console.log("map 메서드를 이용중인 원본 배열: ");
console.log(z)
});

위의 코드 결과 화면

return

map이 종료된 후 결과로는 새로운 배열을 반환한다.

return 값이 없을 경우 배열에는 undefined가 들어간 배열이 생성되므로, 반드시 return 값을 설정해주자.

 

const testArray = [1,2,3,4];

const ResultMap = testArray.map((x)=> {
 console.log(x * 2)   
});

//return 없이 map을 호출했을 때 결과값
console.log(ResultMap);

map 내부에 return이 없을 경우 undefiend로 표시

 


👩‍💻 Map을 활용한 예시

배열 내 객체 원하는 요소만 가져오기

map을 이용할 경우 배열 안에 있는 객체에서 특정값만을 가져와서 배열을 재구성하기가 가능하다.

 

//학생과 해당 학생의 점수
const testArray = [
    {name: '김학생', score: 100},
    {name: '윤학생', score: 90},
    {name: '나학생', score: 80},
];

//맵을 활용하여 점수만 가지와 새로운 배열 생성
const ResultMap = testArray.map((x)=> {
    return x.score
})

console.log(ResultMap);

위 코드 결과 화면

규칙을 활용해 원하는 데이터만 가져오고 싶을 경우

위처럼 간단한 데이터만 가져오는 것이 아니라 조건에 맞는 데이터만 가져오는 것도 가능할까?

배열 내에서 특정 조건을 만족하는 결과 값을 가져와 보도록 하겠다.

 

만약 90점이 넘는 점수를 받은 학생 이름을 알고 싶을 경우를 생각해보자.

 

 //학생과 해당 학생의 점수
const testArray = [
    {name: '김학생', score: 100},
    {name: '윤학생', score: 90},
    {name: '나학생', score: 80},
];

//맵을 활용하여 점수만 가지와 새로운 배열 생성
const ResultMap = testArray.map((x)=> {
    if(x.score >= 90) {
        return x.name
    }
})

console.log(ResultMap);

위 코드 결과 화면

조건을 이용해서 원하는 데이터를 가져오고 싶었지만,

map은 해당 조건이 안 맞을 경우 return 없기 때문에 undefined가 들어간 결과 배열을 가져왔다.

 

이럴 경우, 우리가 알아야 하는 개념이 바로 Filter

 


💎Array.prototype.filter()

filter도 마찬가지로 배열에 for문을 돌아 값을 가져오는 건 map과 동일하나,

차이가 있다면 조건을 주어 해당 조건에 통과하는 값만 가져와 새로운 배열을 만들어준다.

 

맵과 마찬가지로 filter를 이용해도 기존에 호출된 배열은 변하지 않고 원본을 유지하며,

filter에  조건에 부합된 새로운 배열이 생성된다.

 


 

👀 filter의 문법 살펴보기

filter 기본 사용 문법

기본 문법은 map과 모든 게 동일하다.

원본 Array에서 filter을 이용해 callback 함수를 실행하는 방식으로 사용한다.

array.filter((currentValue, index, array) => {});

 

매개변수

매개변수도 map과 모든 게 동일하게,  총 3가지의 매개 변수를 제공한다.

  • CurrentValue :  현재 처리하고 있는 원본 배열의 데이터
  • index :  현재 처리 중인 인덱스
  • array :  현재 map() 메서드를 실행하고 있는 원본 배열

 

//학생과 해당 학생의 점수
const testArray = [
    {name: '김학생', score: 100},
    {name: '윤학생', score: 90},
    {name: '나학생', score: 80},
];

//필터를 활용하여 점수만 가지와 새로운 배열 생성
const ResultMap = testArray.filter((i,x,z)=> {
    console.log(i);
    console.log(x);
    console.log(z);
});

위 코드 결과 값

Return

filter와 map의 가장 큰 차이가 있는 게 바로 반환 결과이다.

map의 경우 return 값을 지정하지 않았을 경우, 강제로 undefined를 넣어주는 반면,

filter의 경우 retrun 값을 지정하지 않거나, 지정한 조건에 모든 값이 해당하지 않을 경우 빈 배열이 반환된다.

 

//학생과 해당 학생의 점수
const testArray = [
    {name: '김학생', score: 100},
    {name: '윤학생', score: 90},
    {name: '나학생', score: 80},
];

//필터를 활용하여 점수만 가지와 새로운 배열 생성
const ResultMap = testArray.filter((x)=> {
    console.log(x.name)
})

console.log(ResultMap);

return이 없을 경우 빈 배열 반환


👩‍💻 Filter를 활용한 예시

배열 내 원하는 숫자 데이터만 가져오고 싶을 경우

배열 안 특정 숫자 조건을 만족하는 데이터를 가져오고 싶을 때도 filter를 활용하면 좋다.

 

//배열 내 10 이하 숫자만 포함하는 배열 만들기

const numberList = [1,11,3,25,9,10,15];
                
const numberResultMap = numberList.filter((x)=> {
	return x <= 10;
});

console.log(numberResultMap)

위 코드 결과 값

배열 내 특정 단어를 포함하는 데이터만 가져오고 싶을 경우

배열 안 특정 단어를 포함하는 데이터를 가져오는 것도 가능하다.

 

const List = ['김사원','윤대리','한주임','윤상무','김주임','최사장','황차장', '김과장'];
 
//indexOf는 해당 글자를 포함하지 않을 경우 -1을 반환한다.
//주임직급을 가진 사람만 가져오기
const ListResultMap = List.filter((x)=> {
	return x.indexOf('주임') !== -1;
});

console.log(ListResultMap);

위 코드 결과 값

규칙을 활용해 원하는 데이터만 가져오고 싶을 경우

map을 이용했을 때 원하는 결과를 못 가져왔던 부분을 filter로 변경해서 진행해보도록 하자.

배열 내에 90점이 넘는 점수를 받은 학생 이름을 알고 싶을 경우를 다시 구현해 보았다.

 

//학생과 해당 학생의 점수
const testArray = [
    {name: '김학생', score: 100},
    {name: '윤학생', score: 90},
    {name: '나학생', score: 80},
];

//맵을 활용하여 점수만 가지와 새로운 배열 생성
const ResultMap = testArray.filter((x)=> {
    if(x.score >= 90) {
        return x.name
    }
})

console.log(ResultMap);

위 코드 결과 값

filter를 이용해 해당 배열의 결과를 가져와보니 undefined는 사라지고,

90점이 넘는 데이터를 가지고 오는 것을 확인할 수 있었다.

 

하지만, 또다른 문제로 이름만 가지고 오는 것이 내가 원하는 결과였지만, 

filter를 이용해 return 되는 건 해당 조건이 만족하는 object 전체가 들어오는 문제가 있다.

(x.name이라고 해당 object에 name만 가져오라는 조건을 주었지만, 객체 전체를 return 해버린다. 🙄)

 

 

👩‍💻 Filter와 map을 동시에 활용한 예시

내가 원하는 결과를 가져오기 위해서는 filter와 map 모든 기능을 활용해야 가져오는 게 가능하다.

다시 한번 90점이 넘는 학새의 이름만 가져오기 위해 filter를 통해 데이터를 거르고, 이름을 가지고 오기 위해 map을 사용했다.

 

//학생과 해당 학생의 점수
const testArray = [
    {name: '김학생', score: 100},
    {name: '윤학생', score: 90},
    {name: '나학생', score: 80},
];

//filter를 이용해 90점 이상한 객체를 가져온다.
//map을 이용하여 해당 객체에 이름을 가져온다.
const ResultMap = testArray.filter((x)=> x.score >= 90).map((x)=> x.name);

console.log(ResultMap);

위 코드 결과 값

 

이처럼 filter와 map을 동시에 활용해서 조건에 부합하는 object를 가져온 뒤,

object의 특정 key의 value값을 가져와 새로운 배열을 만드는 것이 가능한 걸 알 수 있었다.

 


Reference

developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map

developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

 

 

반응형