본문 바로가기
javaScript

javaScript - 배열2 배열 연산

by sinabeuro 2021. 7. 22.
728x90

배열 함수 2편으로 이번에는 배열 함수를 통해서 연산 위주로 살펴보겠습니다.

 

1. map 함수

let books = ['book1', 'book2', 'book3', 'book4', 'book5'];
const bookset1 = books.map( (item) => {
	return {
		title: item,
		author: undefined
	}
});

console.log(bookset1);

console.log(bookset1)의 결과값

map은 객체를 리턴해서 각 객체들을 모아서 배열로 만들어줍니다.

또한 문자열로 구성된 배열을 객체로 구성된 배열로 변환한 것 처럼, 배열을 다른 형태로 변화할 때 map함수가 많이 씁니다.

 

 

2. 이중 map 구조

let books = ['햄릿', '리어왕', '오셀로', '맥베스', 
	'로미오와 줄리엣', '말괄량이 길들이기', '베니스의 상인', '한 여름 밤의 꿈'];
const ShakespeareOneBooks = books
	.map(( item ) => ({
		title: item
	}))
	.map(( item ) => ({
		...book,
		author: "William Shakespeare"
	}));

중간의 과정의 map값이 필요없기을 때 두번 map 메소드를 사용할 수 있습니다.

map은 배열을 리턴하기 때문에 또 다시 map이 가능합니다.

이를 메소드 체이닝이라고 부릅니다.

 

 

함수에 함수를 리턴하는 커링 기법(일급함수 참조)을 사용해서 다시 코드를 작성해보겠습니다.

let books = ['햄릿', '리어왕', '오셀로', '맥베스', 
	'로미오와 줄리엣', '말괄량이 길들이기', '베니스의 상인', '한 여름 밤의 꿈'];
const bookTitleToBookObject = (book) => ({ title: book });
const makeAuthor = (name) => (book) => ({
	...book,
	author: name
});

const shakespeareTwoBooks = books
	.map(bookTitleToBookObject)   // 인자가 생략 시 배열 자신이 넘어간다.
	.map(makeAuthor("William Shakepeare"));  // 두번째 함수의 인자를 생략했음.
    
console.log(shakespeareTwoBooks);

console.log(shakespeareTwoBooks)의 결과값

makeAuthor 함수는 함수에서 함수를 리턴하는 구조입니다.

만약 일반적으로 호출할 경우 makeAuthor(파라미터)(파라미터) 형식으로 호출해야합니다.

하지만 인자를 생략할 수 있습니다. 

위의 예제와 같이 makeAuthor("William Shakepeare")은 내부 함수의 파라미터가 생략되었습니다.

즉, makeAuthor("William Shakepeare")(파라미터)와 같이 파라미터에는 map객체하나의 데이터가 들어가게 됩니다.

결과적으로 books.map(bookTitleToBookObject)의 결과값이 map(makeAuthor("William Shakepeare"))에 넘가는 구조입니다.

 

커링 기법을 사용한 예제나 그냥 map체인을 두번 사용한 예제나 결과값은 같습니다. 

다만 표현력의 차이가 있을 뿐입니다.

 

 

3. filter 함수

const henry = shakespeareTwoBooks.filter((itme) => item.title.includes("헨리"));

includes 문자열이 포함만 되어있으면 true값을 반환하고 없으면 false로 반환합니다.

filter 함수는 return 값이 true인 것만 다시 배열로 만들어서 새로운 배열 값을 반환합니다.

 

 

4. reduce 함수

const someNumbers  = [10, 5, 3 ,14, 56];
const sumNumber = someNumbers.reduce((acc, elm, idx) => acc+elm, 0);
console.log(sumNumber);

const filterNumber = someNumbers.reduce((acc, elm, idx) => { elm>10?acc.push(elm):acc; return acc; }, []);
console.log(filterNumber);

reduces 함수의 첫 인자는 함수입니다. 

reduce 내부 함수의 첫번째 인자가 accumulator 누적값

reduce 내부 함수의 두번째 인자가 currentValue 현재 처리중인 배열 요소

reduce 내부 함수의 세번째 인자가 currentIndex 현재 처리중인 배열 인덱스입니다.

 

reduces 함수의  두번째 인자로 reduce가 반환하는 값과 디폴트 값을 설정합니다.

0으로 설정하면 숫자반환에 디폴트가 0이라는 것이고 []으로 설정하면 배열타입 반환에 디폴트가 빈 배열값입니다.

 

reduces 함수는 상황에 따라 유용하게 사용할 수 있습니다.

filter함수 처럼 값을 거를 때 사용하거나 map함수 처럼 배열을 새로 만들고 배열 요소들의 자료타입을 바꾸고 싶을 때도 사용합니다. 

다시말하면 reduce의 사용 방법은 무궁무진하다는 것이죠!!

 

 

5. 유사 배열

배열처럼 여러 데이터를 가지고 인덱스도 있는 배열과 같은 형태의 자료구조이지만, 배열이 갖고 있는 도구(map, filter, reduce, forEach)는 메소드로서 갖고 있지 않는 자료구조가 유사 배열입니다.

 

대표적으로 함수의 arguments가 유사배열입니다.

 

유사배열을 배열로 바꾸는 방법

function sumNumbers() {
	return Array.from(arguments).reduce( (a, b) => a + b, 0 );
}
console.log(sumNumbers(10, 20, 30, 40, 50));	// 150


// rest parameter로 구현
function sumNumbers(...args) {
	return Array.from(args).reduce( (a, b) => a + b, 0 );
}
console.log(sumNumbers(10, 20, 30, 40, 50)); // arguments 사용 시 빨간줄이 뜬다.

유사배열을 배열로 바꾸려면 Array.from( ) 함수를 사용하면 됩니다.

배열로 변경하면 배열이 사용할 수 있는 메소드를 사용할 수 있게 됩니다.

 

함수 파라미터를 유사배열 형태로 이용할 수 있는 방식은 arguments, rest parameter 두 가지 정도가 있는데, arguments가 좀 더 옛날 방식이라 rest parameter를 사용하는 것이 좋긴합니다.

지만 rest parameter를 Array.from( ) 메소드를 사용하려면 사용 브라우저에서 지원하지 여부를 체크해야합니다.

 

 

728x90

댓글