## 배열 개념 ### 배열 선언 ```javascript // 리터럴 이용하기 const arr1 = [0, 0, 0, 0, 0]; // 생성자 이용하기 const arr2 = new Array(5).fill(0); ``` ### N차원 배열 배열은 차원과는 별개로 메모리에 저장될 때에는 모두 1차원 배열로 저장된다. ```javascript // 1차원 배열 const arr1 = [0, 0, 0, 0]; ``` 2차원 배열은 1차원 배열을 원소로 갖는 배열을 만드는 방식으로 선언할 수 있다. ```javascript const arr2 = [...new Array(3)].map((_, i) => new Array(4).fill(i)); console.log(arr2); ``` > [!tip]- `[...new Array(3)]` 이유 > net Array(3) 는 빈 요소를 3개 담고 있는 배열을 반환한다. `[ <3 empty items> ]` > 이게 undefined랑은 별개의 값임. > map 메서드는 빈 요소는 건너뛰기 때문에 > ```javascript > const arr = new Array(3).map(() => 1); > ``` > 이렇게 map으로 순회할 수 없다. > 하지만 비어있는 배열에 스프레드 연산자를 사용하면 실제로 undefined 값이 채워진 배열로 변환되기 때문에 의도한 대로 map 메서드를 사용할 수 있다. > - 비어 있는 배열 : sparse array > - undefined 값이 채워진 배열 : dense array ## 배열의 효율성 배열은 임의 접근으로 배열의 원소에 접근한다. 따라서 **데이터에 접근하기 위한 시간 복잡도는 `O(1)`**이다. ### 원소 삽입 #### 맨 뒤에 삽입 맨 뒤에는 바로 접근해서 바로 삽입할 수 있으므로 시간 복잡도는 O(1)이다. (`Array.push()`) ![[342e3a68-382b-4b32-bf0e-5f3383e79704.png]] #### 맨 앞에 삽입 맨 앞에 삽입하기 위해서는 뒤 원소들을 모두 한 칸씩 뒤로 밀어낸 뒤에 새로 확보된 자리에 삽입해야 하므로 맨 앞에 삽입하는 시간 복잡도는 `O(N)`이다. (`Array.unshift()`) ![[6dd959fa-41c3-4dc4-b36f-e28ab94b882f.png]] #### 중간에 삽입 중간에 삽입하는 것도 맨 앞에 삽입하는 것과 동일하게 삽입 위치 뒤쪽의 원소들을 한 칸씩 밀어 자리를 확보한 뒤에 삽입하는 방식이 되므로 시간 복잡도는 밀어내야 하는 원소가 N개일 때 `O(N)`이 된다. (`Array.splice()`) ![[0bada834-bc16-4f47-8fc9-64bb1145954e.png]] ### 자료구조로 배열을 선택할 때 고려할 점 배열의 장점으로는 임의접근이 있다. 특히 그래프를 표현할 때 배열을 활용하면 좋다. 하지만 주의할 점이 2가지 있다. 1. **할당할 수 있는 메모리 크기를 확인해야 한다.** 너무 큰 배열을 할당하면 런타임에서 배열 할당에 실패할 수 있다. 운영체제마다 메모리의 한계치는 다르지만, 보통은 정수형 1차원 배열은 1000만개, 2차원 배열은 3000 * 3000 크기를 최대로 생각한다. 2. **중간에 데이터 삽입이 많은지 확인해야 한다.** 선형 자료구조기 때문에 맨 앞이나 중간에 데이터를 빈번하게 삽입하면 시간 복잡도가 높아져서 시간 초과가 발생할 수 있다. ## 자주 사용하는 배열 기법 자주 사용하는 배열 메서드와 구현 패턴 정리 > [!note] shift와 unshift > 배열 특성상 배열 앞에서 원소를 추가하거나 삭제하는 경우에는 시간 복잡도가 O(N)이 되지만 배열 내 데이터가 작은 경우에는 자바스크립트 엔진이 최적화를 하기 때문에 조금 성능이 좋아진다. ### 배열에 데이터 추가 `const arr = [1, 2, 3]` | 방식 | 설명 | 코드 | | ----------- | ---------- | ----------------------------------------------- | | `push()` | 끝에 원소 추가 | `arr.push(4); // [1, 2, 3, 4]` | | `concat()` | 끝에 배열 추가 | `arr.concat([4, 5]); // [1, 2, 3, 4, 5]` | | 스프레드 연산자 | 배열 추가 | `arr = [...arr, ...[4, 5]]; // [1, 2, 3, 4, 5]` | | `unshift()` | 맨 앞에 원소 추가 | `arr.unshift(0); // [0, 1, 2, 3]` | | `splice()` | 배열 중간에 추가 | `arr.splice(3, 0, 4, 5); // [1, 2, 3, 4, 5] ` | ### 배열에 데이터 삭제 `const arr = [1, 2, 3, 4];` | 방식 | 설명 | 코드 | | ---------- | -------- | ----------------------------- | | `pop()` | 끝 원소 제거 | `arr.pop(); // [1, 2, 3]` | | `shift()` | 앞 원소 제거 | `arr.shift(); // [2, 3, 4]` | | `splice()` | 배열 중간 제거 | `arr.splice(1, 2); // [1, 4]` | ## 고차 함수 활용하기 모두 원본 배열은 유지하고 새로운 배열을 반환한다. ### 배열 원소 모두를 제곱하기 (map) ```javascript const numbers = [1, 2, 3, 4]; const squares = numbers.map((number) => number * number); console.log(squares); // [1, 4, 9, 16] ``` ### 짝수 필터링 (filter) ```javascript const numbers = [1, 2, 3, 4]; const evens = numbers.filter((number) => number % 2 === 0); console.log(evens); // [2, 4] ``` ### 총 합 구하기 (reduce) ```javascript const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((sum, number) => sum + number, 0); console.log(sum); // 10 ``` ## 관련 프로그래머스 문제 - [[Lv1. 두 개 뽑아서 더하기]] - [[Lv1. 모의고사]] - [[Lv2. 행렬의 곱셈]] - [[Lv1. 실패율]] - [[Lv2. 방문 길이]]