JavaScript에서 유용하게 쓸 수 있는 내장함수
forEach
- forEach는 기존에 여러 언어에서 두루 쓰이는 for문을 대체할 수 있는 가장 간편한 내장함수다.
const list = [1, 2, 3, 4, 5, 6];
for (let i = 0; i < list.length; i++) {
console.log(list[i]);
}
for문을 사용했을 때의 코드
const list = [1, 2, 3, 4, 5, 6];
list.forEach(value => console.log(value));
내장함수인 forEach를 사용했을 때의 코드
- 위 두 코드와 같이 forEach를 사용하게 되면 기존의 코드를 더 간략하게 축약할 수 있게 된다.
map
- map함수는 매개변수로 함수를 받을 수 있으며 이 함수에 따라 배열의 각 요소들의 값을 변화시킬 수 있다.
//배열의 각 요소들을 제곱한다.
const list = [1, 2, 3, 4, 5, 6];
const resultList = [];
list.forEach((value) => {
resultList.push(value ** 2);
});
console.log(resultList);
forEach로 구현했을 때의 코드
const list = [1, 2, 3, 4, 5, 6];
const resultList = list.map(value => value ** 2);
console.log(resultList);
map을 이용했을 때의 코드
- map의 매개변수를 통해 기존에 선언되어있던 배열의 요소들을 변조해줄 수 있다. 이를 통해 이전에 쓰이던 for나 forEach보다 더 간략하게 코드를 작성할 수 있게 된다.
indexOf
- 찾고자하는 값이 해당 배열의 몇 번째 인덱스에 존재하는지 찾는 것을 도와주는 함수다.
const list = ['a', 'b', 'c', 'd', 'e', 'f'];
//콘솔에 'd'가 저장되어 있는 인덱스인 3이 출력된다.
console.log(list.indexOf('d'));
findIndex
- indexOf에 더해 배열 내부의 값이 객체나 배열일 경우에도 원하는 값의 인덱스를 찾고자 할 때 사용되는 함수다.
const blocks = [
{
name: 's', //네모
center: false,
numberCode: 1,
color: 'red',
currentShapeIndex: 0
}, {
name: 't', //T모양
center: true,
numberCode: 2,
color: 'blueviolet',
currentShapeIndex: 0
}, {
name: 'z', //z자
center: true,
numberCode: 3,
color: 'orenge',
currentShapeIndex: 0
},
{
name: 'rz', //반대z자
center: true,
numberCode: 4,
color: 'skyblue',
currentShapeIndex: 0
}
}
const search = blocks.findIndex(value => value.color === 'orange');
//findIndex의 결과로 해당 속성의 값이 둘어있는 인덱스인 2가 출력된다.
console.log(search);
- findIndex를 이용해 해당 값의 인덱스를 찾을 때 만일 해당 값을 가진 인덱스가 여러개라면 가장 먼저 찾은 인덱스가 반환된다.
find
- findIndex와 같은 프로세스를 가지고 있으나 반환하는 값이 인덱스가 아닌 해당 인덱스의 값 전체를 반환하게 된다는 차이가 있다.
const blocks = [
{
name: 's', //네모
center: false,
numberCode: 1,
color: 'red',
currentShapeIndex: 0
}, {
name: 't', //T모양
center: true,
numberCode: 2,
color: 'blueviolet',
currentShapeIndex: 0
}, {
name: 'z', //z자
center: true,
numberCode: 3,
color: 'orenge',
currentShapeIndex: 0
},
{
name: 'rz', //반대z자
center: true,
numberCode: 4,
color: 'skyblue',
currentShapeIndex: 0
}
];
const search = blocks.find(index => index.name === 'z');
//name속성이 'z'에 해당하는 인덱스의 모든 값이 콘솔에 출력된다.
console.log(search);
- find를 이용해 값을 불러온 후 추가적으로 원하는 속성을 추가로 넣어 해당 값만 뽑아내는 방식도 사용할 수 있다.
...
const search = blocks.find(index => index.name === 'z').color;
//해당하는 요소의 color속성값만 출력된다.
console.log(search);
filter
- filter함수는 기준 배열 내에서 주어진 조건을 만족하는 요소들만 따로 뽑아 새로운 배열을 만드는 역할을 한다.
const blocks = [
{
name: 's', //네모
center: false,
numberCode: 1,
color: 'red',
currentShapeIndex: 0
}, {
name: 't', //T모양
center: true,
numberCode: 2,
color: 'blueviolet',
currentShapeIndex: 0
}, {
name: 'z', //z자
center: true,
numberCode: 3,
color: 'orenge',
currentShapeIndex: 0
},
{
name: 'rz', //반대z자
center: true,
numberCode: 4,
color: 'skyblue',
currentShapeIndex: 0
}
];
//value.center === false는 !value.center와 같은 의미를 가진다.
const filteredBlock = blocks.filter(value => value.center === false);
//center속성의 값이 false가 아닌 모든 요소들이 제거된 후 새로운 값들이 새 배열 변수에 저장된다.
console.log(filteredBlock);
splice
- splice에는 두 개의 매개변수를 사용할 수 있으며 첫 번째 매개변수에는 몇 번째 인덱스부터 지울지를, 두 번째 매개변수에는 해당 인덱스로부터 몇 개의 요소를 지울지에 대한 명령을 기록하게 된다.
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
//3번 인덱스를 포함해 뒤로 5개를 지우도록 명령한다.
list.splice(3, 5);
console.log(list);
- 인덱스를 직접 입력하는 대신 indexOf나 findIndex 등을 활용해 원하는 값에 대한 인덱스값을 먼저 추출한 후 splice를 진행하는 방법도 있다.
...
const index = list.indexOf(9);
//list.splice(list.indexOf(9), 4)와 같이 축약해서 작성해도 무방하다.
list.splice(index, 4);
console.log(list);
slice
- splice와 같은 기능을 가지고 있지만 기존에 존재하던 배열을 건드리지 않고 새로운 배열을 생성하여 결과값을 저장한다는 차이가 있다.
const list = [1, 2, 3, 4, 5];
const sliceList = list.slice(2, 2);
//기존에 존재하던 list배열은 내부 요소에 변화가 없음을 알 수 있다.
console.log(sliceList);
console.log(list);
shift & unshift
- shift함수는 배열의 첫 번째 인덱스값을 해당 배열에서 제거하는 역할을 한다.
const list = [1, 2, 3, 4, 5];
const lose = list.shift();
//shift함수를 통해 추출된 값인 1이 출력된다.
console.log(lose);
- shift함수는 가장 뒤의 요소를 추출해주는 pop()함수와는 정 반대의 기능을 한다고 보면 된다.
- unshift는 shift와는 달리 가장 앞에 해당하는 값을 넣어주는 역할을 한다.
const list = [1, 2, 3, 4, 5];
list.unshift(10);
//가장 앞에 10이 추가된 [10, 1, 2, 3, 4, 5]가 출력된다.
console.log(list);
//아래와 같이 반복문을 활용해 여러개의 값을 배열의 앞에 추가해주는 방식도 사용 가능하다.
for (let i = 0; i < 5; i++) {
list.unshift(i);
}
concat
- concat함수는 여러 개의 배열들을 하나의 배열로 합쳐주는 역할을 한다.
const list1 = [1, 2, 3, 4];
const list2 = [5, 6, 7, 8];
const list3 = [2, 4, 6, 8];
const mixedList = list1.concat(list2.concat(list3));
//세 가지 배열이 모두 합쳐진 배열이 완성된다.
console.log(mixedList);
join
- join함수는 배열 내의 요소들을 매개변수로 넣은 구분자를 기준으로 문자열 형태로 합치는 역할을 한다.
- 만일 별다른 구분자를 매개변수에 입력하지 않게 되면 ,이 기본값으로서 지정된다.
const list = [1, 2, 3, 4];
//1,2,3,4
console.log(list.join());
//1234
console.log(list.join(''));
//1 | 2 | 3 | 4
console.log(list.join(' | '));
//1 & 2 & 3 & 4
console.log(list.join(' & '));
- 임의의 문자열에 join함수와 split함수를 사용하게 되면 공백 없는 문자열을 만들어줄 수도 있다.
const line = 'Have a good day!';
const changedLine = line.split(' ').join('');
reduce
- 사용하는 바에 따라 활용도가 무궁무진하게 변화할 수 있는 내장함수다.
- 기본적으로는 map과 유사하게 함수를 매개변수로서 받게 된다.
- 함수에는 두 가지 매개변수를 선언할 수 있으며 첫 번째 매개변수에는 함수에 대한 결과가 누적되어 저장되며 두 번째 매개변수는 reduce함수에서 사용하게 될 누적 변수의 초기값을 저장하게 된다.
const list = [1, 2, 3, 4, 5, 6];
let multifyList = list.reduce((accumulator, current) => accumulator * current, 1);
console.log(multifyList);
- reduce함수에 의해 모든 배열의 요소들을 곱한 값이 multifyList변수에 저장된다.
한 가지 문제를 해결할 세 가지 방법
- 숫자로 이루어진 배열이 있을 때 이를 10 보다 큰 요소들의 개수를 반환해주는 함수를 만든다.
1. forEach를 활용하는 방법
const func = (arr) => {
let count = 0;
arr.forEach((value) => {
if (value > 10) {
++count;
}
});
return count;
};
const list = func([1, 2, 3, 4, 5, 10, 20, 30, 40, 50]);
console.log(list);
2. filter를 활용하는 방법
const func = (arr) => {
return arr.filter(value => value > 10).length;
};
const list = func([1, 2, 3, 4, 5, 10, 20, 30, 40, 50]);
console.log(list);
3. reduce를 활용하는 방법
const func = (arr) => {
return arr.reduce((accumulator, current) => {
if (current > 10) {
return ++accumulator;
} else { //else를 통해 예외상황을 확실하게 처리해주지 않으면 NaN이 결과로 출력되는 문제가 발생한다.
return accumulator;
}
}, 0);
};
const list = func([1, 2, 3, 4, 5, 10, 20, 30, 40, 50]);
console.log(list);
- reduce를 사용할 때는 return을 확실하게 기입하여 결과를 저장하는 것에 더해 조건문을 사용하고자 한다면 else를 확실하게 사용해 어느 조건에도 포함되지 않을 때의 처리도 지정해두는 것이 중요하다는 것을 알 수 있었다.
- 그냥 위 세가지 방식을 비교해보았을 때 reduce를 사용하는 것이 filter나 map, forEach를 사용하는 것에 비해 어떤 면이 더 유리한 지 확신이 되지 않는다.
- reduce는 코드가 더 복잡해질수록 점점더 재사용성 등의 효율이 증가하게 된다.
const list = [1, 2, 3, 4, 5, 6];
const resultList = []
const func = (accumulator, current) => {
if (current % 2 !== 0) {
accumulator.push(current * 2);
}
return accumulator;
};
const resultWithReduce = list.reduce(func, resultList);
const resultWithFilterAndMap = list.filter(value => value % 2 !== 0).map(value => value * 2);
- reduce를 사용하게 되면 배열을 한 번만 순회하는 중에 문제가 해결되는 반면, filter와 map은 조건에 맞는 요소를 추출하는 과정과 해당 요소를 곱하는 과정을 거치며 배열을 두 번 순회하게 되어 효율이 떨어지는 것을 볼 수 있다.
- reduce를 사용함에 있어 드러나는 또다른 장점으로는 문제 해결을 위해 정의해둔 함수를 다른 코드에서도 재사용할 수 있게 된다는 것이다.
'프로그래밍 > JavaScript' 카테고리의 다른 글
프토토타입 & 클래스 (0) | 2019.12.07 |
---|---|
자바스크립트 문제 풀이 (2) (0) | 2019.11.28 |
자바스크립트 문제 풀이 (1) (0) | 2019.11.26 |
var과 let, const (0) | 2019.08.22 |
this (0) | 2019.08.21 |