안녕하세요! 오늘은 유용하게 사용할 수 있는 배열메서드들에 대해 알아보겠습니다.
배열메서드는 바닐라JS뿐 아니라 React등 많이 사용하는 라이브러리, 프레임워크들에서도 사용도가 높습니다.
먼저! 배열메서드에는 어떤 것들이 있는지 보겠습니다.
map() : 형태를 바꿀 수 있지만 길이는 유지됩니다.
sort() : (정렬) 순서만 바꿉니다. (형태나 길이는 변경되지않습니다.)
filter() : (필터) 원하는 기준에따라 길이를 변경합니다.(형태를 변경하지 않습니다.)
find() : (필터) 한 개의 데이터를 찾습니다. (형태를 변경하지 않습니다.)
forEach() : (반복) 형태를 이용해 반복작업을 합니다. 반환값이 없습니다.
reduce() : 무엇이든 할 수 있습니다. (길이와 형태를 바꾸거나 새로운 데이터를 만들 수 있습니다.)
먼저 예제에 더미데이터를 사용해보겠습니다.
mockaroo 링크로 들어가서 커스텀 더미데이터를 다운받을 수 있습니다.
const carData = [
{ id: 10, '제조사': 'Lamborghini', '이름': 'Murciélago' },
{ id: 9, '제조사': 'Volkswagen', '이름': 'Passat' },
{ id: 8, '제조사': 'Buick', '이름': 'Estate' },
{ id: 7, '제조사': 'Infiniti', '이름': 'G' },
{ id: 6, '제조사': 'Panoz', '이름': 'Esperante' },
{ id: 5, '제조사': 'Subaru', '이름': 'Brat' },
{ id: 4, '제조사': 'Hyundai', '이름': 'Santa Fe' },
{ id: 3, '제조사': 'Honda', '이름': 'Civic' },
{ id: 2, '제조사': 'Lexus', '이름': 'SC' },
{ id: 1, '제조사': 'Infiniti', '이름': 'EX' }
]
가상의 데이터를 다운받아봤습니다.
그런데 id가 내림차순입니다. sort()메서드를 이용해서 오름차순으로 바꿔보겠습니다.
sort()에 대해서는 지난시간에 게시했었던 sort()에대한 게시물을 참고하시면 됩니다.
원본을 조작하지않고 복사본으로 진행하고싶다면
[...carData].sort((a,b)=>a.name-b.name)
이렇게 하면 되겠습니다.
const copied = [...carData];
copied.sort((a,b)=>a.id-b.id)
계속 사용할 복사본이라면 이렇게 변수에 할당해 사용합시다.
이번엔 map()메서드를 이용해서 제조사목록을 배열로 반환받아보겠습니다.
const manufacturer =copied.map(item => {
return item.제조사
})
/*
[
'Infiniti', 'Lexus',
'Honda', 'Hyundai',
'Subaru', 'Panoz',
'Infiniti', 'Buick',
'Volkswagen', 'Lamborghini'
]
*/
map()을 이용해 각 요소에 대한 리턴값을 작성하면, 메서드가 리턴값들로 새로운 배열을 생성해 반환합니다.
배열의 각각 요소를 어떻게 반환할지에 집중해 return값을 수정하면 됩니다.
계속해서 manufacturer배열을 이용해보겠습니다.
제조사 이름의 길이가 6글자 이상인 항목을 찾아보겠습니다.
const filtered = manufacturer.filter(man => man.length >= 6)
console.log(filtered)
/*
[
'Infiniti',
'Hyundai',
'Subaru',
'Infiniti',
'Volkswagen',
'Lamborghini'
]
*/
지금까지 sort() , map() , filter() 메서드를 거쳤습니다.
이 메서드들은 체이닝으로 쉽게 사용할 수 있습니다.
const filtered = [...carData]
.sort((a,b)=>a.id-b.id)
.map(item=>item.제조사)
.filter(man => man.length>=6);
다음을 실행하면 같은 결과값을 얻을 수 있습니다.
배열메서드의 큰 장점입니다.
find()메서드는 filter()와 유사합니다.
console.log(carData.find(car => car.제조사 === 'Infiniti'))
carData에서 car.제조사가 Infiniti에 해당하는 항목을 반환합니다.
하지만, Infiniti에 해당하는 값은 결과값은 두개입니다.
반환값은 어떻게 될까요? 하나만 반환됩니다.
결과값 중 첫 번째 항목만 반환되게 됩니다.
그리고
filter()메서드는 결과값이 없을경우 빈 배열을 반환하지만,
find()메서드는 undefined를 반환합니다.
위 코드를 다시 작성해보겠습니다.
console.log(carData.find(car => car.제조사 === 'lego') || '결과값 없음')
여기서는 콘솔에만 출력해봤지만,
삼항연산자로 기본값을 출력할 수 있다는 것을 기억해주세요.
이번에는 forEach()에 대해서 보겠습니다.
forEach()는 부수효과가 일어난다는 것을 명시적으로 코드에 보여줄 때 사용하면 좋습니다.
부수효과는 함수의 유효범위 밖에 있는 무언가를 변경하는 것 입니다.
함수의 유효범위 내의 작업은 다른 메서드들을 사용하고
부수효과가 있을 경우에만 forEach()를 사용한다면 명시적으로 예측가능성을 높힐 수 있는 코드가 됩니다.
선언자 let을 남용하지않고 필요한 경우에만 let을 사용하는 것과 유사합니다.
이어서 코드를 보겠습니다.
function getId(item) {
console.log(item.id)
/*
...
...
대충 item.id를 이용해 뭔가를 하는 작업
...
*/
}
carData.filter(car=> car.제조사.length >= 6)
.forEach(item => getId(item))
carData에서 제조사의 길이가 6이상인 항목들에 대해 getId()함수를 실행시킵니다.
이렇게 부수효과를 일으키는 경우, map()메서드 안에서 할 수 도 있겠지만, 따로 작성해 가독성을 높히는게 좋습니다.
마지막으로 reduce차례입니다.
많은 것을 할 수 있는 reduce()는 작성할게 많은만큼
다음게시물에 따로 작성하겠습니다!!!