본문 바로가기

웹개발/프론트관련

[JavaScript] 배열 다루기 (map, reduce, filter 등)


(jQuery !== JavaScript)


스크립트에 크게 관심이 없으신 분들은 순수 Javscript를 보통 for문이나 if문에서만 사용하게 될텐데 이번에는 javascript로 간단한 배열들을 다뤄 보겠습니다.  

1. Map 활용하기

예) 모든 배열의 요소 10자리수로 증가시키기


   
// for 문 사용
var num = [2, 4, 6, 8];
var result = [];

for (var i = 0; i < num.length; i++) {
result.push(num[i] * 10);
};

console.log(result); // [ 20, 40, 60, 80 ]


MDN :
map() 메소드는 배열 내의 모든 요소 각각에 대하여  제공된 함수(callback)를 호출하고 그 결과를 모아서 새로운 배열을 반환합니다.

var num = [2, 4, 6, 8];
var result = num.map(function(num) { return num * 10; });

console.log(result); // [ 20, 40, 60, 80 ]


2. Reduce 활용하기

예) 1 부터 10까지의 모든 값을 더하기


// for 문 사용
var sumArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = 0

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

console.log(result);     // 결과 55

네 보통 간단한 for문으로 구현 가능합니다.
하지만 더 간단하게 한 줄로 가능합니다.


MDN :
reduce() 메서드는 왼쪽에서 오른쪽으로 이동하며 배열의 각 요소마다 누적 계산값과 함께 함수를 적용해 하나의 값으로 줄입니다.

// Reduce 사용
var sumArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = sumArr.reduce(function(prev, curr) { return prev + curr; });

console.log(result);     // 결과 55

Reduce는 워낙 헷갈릴 수 있어 1절만 다루고 설명은 생략했습니다.(MDN에서 보시면 됩니다)
실제로는 더욱더 다양하게 활용할 수 있습니다.


3. Filter + 함수형 프로그래밍

예) Java를 배우는 사람만 출력하기

var persons = [
{ name: "aaa", learn: "javascript" },
{ name: "bbb", learn: "javascript" },
{ name: "ccc", learn: "java" },
{ name: "ddd", learn: "javascript" }
];


// 전형적인 for & if 문 조합
var result = '';

for (var i = 0; i < persons.length; i++) {
if (persons[i].learn === 'java') {
result = persons[i];
}
}

console.log(result);     // { name: 'ccc', learn: 'java' }


MDN :
filter() 메소드는 제공된 함수로 구현된 테스트를 통과하는 모든 요소가 있는 새로운 배열을 만듭니다.


// filter를 활용한 함수형 프로그래밍
var isJava = function(person) {
return person.learn === 'java';
}

var result = persons.filter(isJava);

console.log(result);     // { name: 'ccc', learn: 'java' }



4. Some + 함수형 프로그래밍

예) 적폐 세력을 숨겨주는 팀 찾아내기

for문 구현은 생략하겠습니다.

|| (or) 연산자와 비슷하다고 보면 됩니다
&& (and) 연산자와 비슷한 모든 요소의 참을 구하는 경우는 every를 사용하면 됩니다.


MDN :
some() 메소드는 배열 내 일부 요소가 제공된 함수에 의해 구현된 테스트를 통과하는 지를 테스트합니다.
var aTeam = [
{id : 1, name : "Steven Paul Jobs", xMan : false},
{id : 2, name : "Steve Gary Woz Wozniak", xMan : false},
{id : 3, name : "James Arthur Gosling,", xMan : false},
];
var bTeam = [
{id : 1, name : "Dennis MacAlistair Ritchie", xMan : false},
{id : 2, name : "Linus Benedict Torvalds", xMan : false},
{id : 3, name : "Little Rocket Man", xMan : true},
];
var cTeam = [
{id : 1, name : "Mark Zuckerberg", xMan : false},
{id : 2, name : "William Henry Gates", xMan : false},
{id : 3, name : "Brendan Eich", xMan : false},
];

// X맨에 대한 조건
var isXman = function(arr) { return arr.xMan; }

console.log(aTeam.some(isXman));     // false
console.log(bTeam.some(isXman));     // true (적폐 발견)
console.log(cTeam.some(isXman));     // false

5. map & filter & reduce를 모두 사용하여 회사 내에 남성 개발자 중 최고 연봉의 세전 월급을 구하라


var person =[
{ "name": "Corrine Keller", "age": 34, "gender": "female", "salary": 7019 },
{ "name": "Parks Sargent", "age": 33, "gender": "male", "salary": 7430 },
{ "name": "Phelps Fleming", "age": 21, "gender": "male", "salary": 5392 },
{ "name": "Kristine York", "age": 24, "gender": "female", "salary": 3043 },
{ "name": "Cooley Howard", "age": 29, "gender": "male", "salary": 2980 },
{ "name": "Chavez Mcmillan", "age": 29, "gender": "male", "salary": 7052 },
{ "name": "Christina Price", "age": 33," gender": "female", "salary": 7792 },
{ "name": "Sullivan Hopkins", "age": 39, "gender": "male", "salary": 4847 },
{ "name": "Rosalie Stafford", "age": 31, "gender": "female", "salary": 2782 },
{ "name": "Yang Bradshaw", "age": 27, "gender": "male", "salary": 6527 },
{ "name": "Adams Powell", "age": 30, "gender": "male", "salary": 3141 },
{ "name": "Fry Ellison", "age": 31, "gender": "male", "salary": 4310 },
{ "name": "Pearl Jensen", "age": 32, "gender": "female", "salary": 2778 },
{ "name": "Margery Pope", "age": 39, "gender": "female", "salary": 2898 },
{ "name": "Nixon Chambers", "age": 24, "gender": "male", "salary": 3698 },
{ "name": "Paulette Tyler", "age": 20, "gender": "female", "salary": 8015 },
{ "name": "Rosales Delacruz", "age": 40, "gender": "male", "salary": 6823 }
]

// 배열의 요소 중 gender의 값이 male인지 체크
var isMale = function(person) { return person.gender === 'male'; }

// 배열의 요소 중 salary를 3으로 곱한다
var threeYearSalary = function(person) { return parseInt(person.salary / 12); }

// Math.max를 활용하여 최대 값을 뽑아낸다
var isMax = function(a, b) { return Math.max(a, b); }

var result = person
.filter(isMale)
.map(threeYearSalary)
.reduce(isMax);

console.log(result);


JavaScript의 내장 Array를 사용하면 정말 다양한 자료구조를 쉽게 구현할 수 있습니다.

아 그리고 JavaScript 신기술 아니냐고 묻는 친구들이 가끔 있는 데 신기술이 아닙니다

5년도 넘은 ECMAScript 5.1 버전이며 IE9 이상이면 넘어도 사용 가능합니다.

SI환경을 고랴하여 IE9 에서도 지원되는 것들만 골라서 소개했으니 도움이 되었으면 좋겠습니다. 

참고로 ECMAScript 2015 (일명 ES6)를 사용하면 더욱 짧은 코드도 생성할 수 있습니다.


// 1부터 5까지의 숫자 모두 더하기

[1, 2, 3, 4, 5].reduce((prev, curr) => prev + curr);     // 결과 15


다들 Java나 jQuery는 이미 잘하시겠지만 JavaScript도 다양한 방법의 구현이 가능하고 이미 대중화가 있으니 함수형 프로그래밍과 원본 배열을 훼손하지 않고 새로운 배열을 만들어내는 방식이 왜 중요한지
생각해보시면서 참고하시면 좋을 것 같습니다.