javascript로 array 다루는 13가지 방법 feat 다양한 문법
들어가며
JavaScript는 웹 개발에서 매우 중요한 언어로, 다양한 환경에서 강력한 기능을 제공한다. 특히 배열과 객체는 JavaScript 프로그래밍에서 핵심적인 부분을 차지하고 있다. 이 글에서는 JavaScript를 사용하여 배열을 다루는 방법과 함께 다양한 문법과 기법들을 소개하려 한다.
먼저, 기본적인 for
및 while
반복문을 사용한 배열 조작 방법을 살펴본다. 이는 JavaScript 배열을 다루는 가장 기본적인 기술이다. 그 다음으로, forEach
, filter
, reduce
, map
과 같은 고급 배열 메소드를 통해 배열 조작의 다양한 측면을 탐구한다. 이러한 메소드들은 코드를 더 간결하고 효율적으로 만들어주는 강력한 도구이다.
이어서, for...in
, for...of
같은 반복문을 사용하는 방법을 다루며, 배열과 객체의 속성에 접근하는 다양한 방법을 소개한다. 마지막으로, Object.keys
, Object.entries
, Object.values
같은 Object 메소드들을 이용한 배열 조작 방법을 다루어, 배열과 객체를 더 깊이 이해할 수 있도록 한다.
이 글을 통해 JavaScript의 배열과 객체를 다루는 다양한 방법을 배워, JavaScript 프로그래밍 능력을 한 단계 업그레이드할 수 있기를 기대한다.
모든 예제는 1부터 100까지 짝수가 들어가 있는 배열을 만드는 것을 목표로 한다. 동일한 목표지만 얼마나 많은 방법이 있는지, 글을 준비하면서도 재미있었다.
기본적인 방법들 - for, while 사용
for
반복문은 시작 조건, 종료 조건, 반복마다 실행되는 업데이트 부분으로 구성되어 있다. 블럭내에서는 간단하게 push를 실행하면 된다. push는 array를 다루는 가장 기본적인 명령으로, 아이템을 배열의 끝에 하나 추가해준다.
const evenNumbers = [];
for (let i = 2; i <= 100; i += 2) {
evenNumbers.push(i);
}
while
반복문은 주어진 조건이 참인 동안 계속해서 코드 블록을 실행한다.
const evenNumbers = [];
let i = 2;
while (i <= 100) {
evenNumbers.push(i);
i += 2;
}
forEach, filter, reduce, map 사용
JavaScript의 forEach
, filter
, reduce
, map
과 같은 배열 메소드들은 배열을 다루는 데 매우 유용하다. 이 메소드들을 활용해 1부터 100까지의 짝수 배열을 만들 수 있다.
이 예제 이후로는 1~50의 숫자가 들어있는 temp50, 1~100의 숫자가 들어있는 temp100 배열이 있다고 가정하겠다.
forEach
메소드 사용하기
forEach
메소드는 배열의 각 요소에 대해 주어진 함수를 실행한다. 이를 사용해 temp50
배열의 각 요소를 두 배로 만들어 1부터 100까지의 짝수 배열을 만들 수 있다.
const evenNumbers = [];
temp50.forEach(val => evenNumbers.push(val * 2));
filter
메소드 사용하기
filter
메소드는 주어진 조건에 맞는 모든 요소를 새로운 배열로 반환한다. temp100
배열에서 짝수만 필터링하여 짝수 배열을 만들 수 있다.
const evenNumbers = temp100.filter(val => val % 2 === 0);
map
메소드 사용하기
map
메소드는 배열의 모든 요소에 대해 주어진 함수를 호출한 결과를 모아 새로운 배열을 만든다. temp50
배열의 각 요소를 두 배로 만들어 1부터 100까지의 짝수 배열을 만들 수 있다.
const evenNumbers = temp50.map(val => val * 2);
reduce
메소드 사용하기
reduce
메소드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환한다. 이 메소드를 사용해 temp50
배열의 각 요소를 두 배로 만들어서 하나의 새로운 배열을 생성할 수 있다.
const evenNumbers = temp50.reduce((acc, cur) => {
acc.push(cur * 2);
return acc;
}, []);
const evenNumbers = temp50.reduce((acc, cur) => {
return acc.concat([cur * 2]); // 안좋은 예
}, []);
아래의 예는 위의 예보다 효율적이지 못하다. concat
메소드는 매 반복마다 새로운 배열을 생성하고 반환하기 때문이다. 반면, push
메소드는 기존의 누적자(acc
) 배열에 요소를 추가하기만 하므로 새로운 배열을 만들 필요가 없어 성능과 메모리 면에서 이점이 있다.
for ... in , for ... of 사용하기
JavaScript에서 for...in
과 for...of
는 배열이나 객체의 요소를 순회하는 데 사용되는 반복문이다.
for...in
은 객체의 모든 열거 가능한 속성에 대해 반복을 수행한다.
배열(array)은 객체(object)의 일종이고 배열에서의 index가 key역할을 한다. index가 key이기 때문에 모든 javascript의 다른 객체와 마찬가지로 key의 type은 string 형태가 된다.
이런 이유로 for...in
을 사용할 때 인덱스는 기본적으로 문자열로 처리되게 되고, 숫자 연산을 수행하기 위해서는 Number
또는 parseInt
함수로 타입 변환을 해야 한다.
const evenNumbers = [];
for(var key in temp50) {
evenNumbers.push(Number(key) * 2 + 2)
}
for...of
는 반복 가능한 객체(예: 배열, 문자열, Map, Set 등)의 요소에 대해 반복을 수행한다. 배열에서 사용하면 배열의 각 값에 직접 접근할 수 있다.
const evenNumbers = [];
for(var val of temp50) {
evenNumbers.push(val * 2)
}
기타 배열 method 사용하기 - from, fill
JavaScript에서는 배열을 생성하고 조작하기 위해 다양한 내장 메소드를 제공한다.
Array.from
과 map
메소드를 사용하면, 쉽고 간결하게 배열을 만들고 변형할 수 있다. Array.from
메소드는 배열이나 배열과 유사한 객체로부터 새 배열 인스턴스를 생성할 때 사용된다. 이 메소드를 사용하여 1부터 100까지의 짝수 배열을 간단하게 만들 수 있다.
const evenNumbers = Array.from({length: 50}, (_, index) => (index + 1) * 2);
또한, Array.fill
과 map
을 조합하여 배열을 생성하고 초기화할 수 있다.
const evenNumbers = new Array(50).fill().map((_, i) => i * 2 + 2);
여기서 우리가 index(i)만 사용할거라면 new Array(50).map(...); 으로 해도 되지 않을까 하는 생각을 할 수 있다.
const evenNumbers = new Array(50).map((_, i) => i * 2 + 2);
이렇게 작성하면 원하는 결과를 얻을 수 없는 이유는 JavaScript에서 new Array(50)
를 사용하여 생성된 배열이 "empty" 슬롯을 갖기 때문이다. 이 "empty" 슬롯은 실제로 정의되지 않은 상태이며, map
과 같은 배열 메소드는 이러한 "empty" 슬롯을 무시한다.
new Array(50)
는 길이가 50인 배열을 생성하지만, 배열의 각 위치는 "empty" 상태이다. "empty"는 undefined
나 null
과 다르게 완전히 공간 자체가 비어있다는 것을 의미한다. 따라서 map
, forEach
, filter
등과 같은 배열 메소드들은 이러한 "empty" 슬롯을 건너뛰고, 따라서 아무런 동작도 수행하지 않는다.
반면에, new Array(50).fill()
은 배열의 모든 슬롯을 undefined
나 다른 지정된 값으로 채운다. 이렇게 하면 각 슬롯이 "empty" 상태가 아니게 되어, map
과 같은 메소드들이 정상적으로 각 요소에 접근하여 연산을 수행할 수 있다. 그래서 위와 같이 fill
메소드를 사용하여 배열을 초기화한 후에 map
을 사용하는 것이다.
Object.keys, Object.entries, Object.values 사용 - array는 object니까
Object.keys
메소드는 객체의 모든 키를 배열로 반환한다. 이를 map
과 결합하여, 객체의 각 키에 대해 연산을 수행하고 결과를 배열로 반환할 수 있다. 물론 key는 string형식이므로 숫자형으로 바꿔줘야 한다.
const evenNumbers = Object.keys(temp50).map(key => Number(key) * 2 + 2);
Object.entries
메소드는 객체의 각 속성에 대해 [키, 값]
형태의 배열을 반환한다. 이를 map
과 결합하여 객체의 각 속성에 대한 변환 작업을 수행할 수 있다.
const evenNumbers = Object.entries(temp50).map(([key, val]) => val * 2);
Object.values
메소드는 객체의 모든 값을 배열로 반환한다. 이를 map
과 결합하여, 객체의 각 값에 대한 연산을 수행하고 결과를 배열로 반환할 수 있다.
const evenNumbers = Object.values(temp50).map(val => val * 2);
결론
이 글에서 살펴본 것처럼, JavaScript에서 1부터 100까지의 짝수 배열을 구하는 방법은 매우 다양하다. 실제로, 일부 방법은 이런 간단한 작업을 위해 다소 과하다고 느껴질 수도 있다. 하지만 이러한 다양한 접근 방식들은 JavaScript를 연습하고, 언어의 다양한 기능을 탐구하는 데 매우 유용하다.
JavaScript는 유연하고 강력한 언어로, 같은 문제를 해결하기 위해 여러 다른 방법을 제공한다. 이러한 다양성은 개발자에게 상황에 맞는 최적의 해결책을 선택할 수 있는 유연성을 부여한다. 어떤 경우에는 간단한 for
반복문이 가장 적합할 수 있고, 다른 경우에는 map
, filter
와 같은 고급 배열 메소드나 Object
와 관련된 함수들이 더 나은 선택이 될 수 있다.
이 글을 통해 소개된 다양한 방법들을 기억하고, 실제 문제 해결 시 이러한 기법들을 적절하게 활용하여 상황에 맞는 유연한 접근을 하는 것이 중요하다. JavaScript의 깊이 있는 이해와 능숙한 사용은 개발자로서의 능력을 크게 향상시킬 것이다.