자바스크립트 (배열)

이종경·2024년 4월 16일
0

자바스크립트

목록 보기
7/11
post-thumbnail

1. 자바스크립트의 배열은 배열이 아니다

자바스크립트 배열은 인덱스를 프로퍼티 키로 갖으며 length 프로퍼티를 갖는 특수한 객체이다.
자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 배열 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조적인 단점을 갖는다. 하지만 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대할 수 있다.

2. 빈 배열을 만드는 방법

아래와 같이 두 가지 방법이 있다.

const arr = new Array(5); // length가 5인 빈 배열을 생성한다.
console.log(arr) // (5) [empty × 5]

const arr2 = Array.from({ length:5 }); // length가 5인 유사 배열 객체를 변환한다
console.log(arr2) // (5) [undefined, undefined, undefined, undefined, undefined]

3. 배열의 변환

유사 배열 객체(array-like object) 또는 이터러블 객체(iterable object)를 변환하여 새로운 배열을 생성한다.

// 유사 배열 객체를 새로운 배열을 변환하여 반환한다.
const arr1 = Array.from({ length: 2, 0: 'a', 1: 'b' });
console.log(arr2); // [ 'a', 'b' ]

// Array.from의 두번째 매개변수에게 배열의 모든 요소에 대해 호출할 함수를 전달할 수 있다.
// 이 함수는 첫번째 매개변수에게 전달된 인수로 생성된 배열의 모든 요소를 인수로 전달받아 호출된다.
const arr3 = Array.from({ length: 5 }, function (v, i) { return i; });
console.log(arr3); // [ 0, 1, 2, 3, 4 ]

유사 배열 객체 : 배열처럼 보이지만 사실 key가 숫자이고 length 값을 가지고 있는 객체를 말한다

또한, 리액트에서 컴포넌트를 반복할때 사용된다.

// + 버튼을 클릭한 횟수 만큼 컴포넌트 반복 렌더하기

// useState
const [count, setCount] = useState(0);

// 버튼 컴포넌트
 <Button onClick={() => setCount(p => p + 1)}>+</Button>

// 추가 하기 버튼을 클릭한 만큼 Row 컴포넌트 반복하기
{Array.from({length:count}).map((_,i) => (
  <div key={i}>
  	<Row/>	
  </div>
)}

4. 두 배열을 하나의 배열로 만들기

concat()을 이용한 원본 배열 유지

const arr1 = [1, 2];
const arr2 = [3, 4];

// 배열 arr2를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환
// 인수로 전달한 값이 배열인 경우, 배열을 해체하여 새로운 배열의 요소로 추가한다.
let result = arr1.concat(arr2);
console.log(result); // [1, 2, 3, 4]

console.log(arr1) // [1, 2]

스프레드 연산자를 이용한 원본 배열 유지

const arr1 = [1, 2];
const arr2 = [3, 4];

// 스프레드 연산자를 이용하여 새로운 배열을 반환
const combined = [...arr1, ...arr2];

console.log(combined); // [1, 2, 3, 4]

console.log(arr1); // [1, 2]

reduce()을 이용한 원본 배열 변경

const arr1 = [1, 2];
const arr2 = [3, 4];

// reduce 메서드를 사용하여 arr2의 각 요소를 arr1에 합치기
const combined = arr2.reduce((accumulator, currentValue) => {
  accumulator.push(currentValue);
  return accumulator;
}, arr1); // arr1을 초기값으로 설정

console.log(combined); // [1, 2, 3, 4]

console.log(arr1); // [1, 2]

5. push()메서드는 쓰지말자

push() 메서드는 원본 배열을 변경할뿐만 아니라 성능면에서도 좋지 않다.
따라서 push() 메서드를 사용하는 것보단 스프레드 연산자를 통해 원본 배열을 유지하거나, 원본 배열에 새로운 값을 추가할 땐 아래와 같은 방식으로 추가하는 것이 좋다.

const arr = [1, 2];

// arr.push(3)와 동일한 처리를 한다. 이 방법이 push 메소드보다 빠르다.
arr[arr.length] = 3;

console.log(arr); // [1, 2, 3]

6. slice()와 splice()

slice()

인자로 지정된 배열의 부분을 복사하여 반환한다. 원본 배열은 변경되지 않는다.

Array.prototype.slice(start=0, end=this.length)
const items = ['a', 'b', 'c'];

// items[0]부터 items[1] 이전(items[1] 미포함)까지 반환
let res = items.slice(0, 1);
console.log(res);  // [ 'a' ]

// items[1]부터 이후의 모든 요소 반환
res = items.slice(1);
console.log(res);  // [ 'b', 'c' ]

// 인자가 음수인 경우 배열의 끝에서 요소를 반환
res = items.slice(-1);
console.log(res);  // [ 'c' ]

// 원본은 변경되지 않는다.
console.log(items); // [ 'a', 'b', 'c' ]

slice 메소드에 인자를 전달하지 않으면 원본 배열의 복사본을 생성하여 반환한다. 이때 원본 배열의 각 요소를 얕은 복사(shallow copy)하여 새로운 복사본을 생성한다.

const arr = [1, 2, 3];

// 원본 배열 arr의 새로운 복사본을 생성한다.
const copy = arr.slice();
console.log(copy, copy === arr); // [ 1, 2, 3 ] false

console.log(copy[0] === arr[0]) // true

splice()

기존의 배열의 요소를 제거하고 그 위치에 새로운 요소를 추가한다. 배열 중간에 새로운 요소를 추가할 때도 사용된다. splice() 메서드는 원본 배열이 변경된다.

Array.prototype.splice(start: number, deleteCount=this.length-start, …items: T[])

deleteCount : 시작 위치(start)부터 제거할 요소의 수이다. deleteCount가 0인 경우, 아무런 요소도 제거되지 않는다. (옵션)
items : 삭제한 위치에 추가될 요소들이다. 만약 아무런 요소도 지정하지 않을 경우, 삭제만 한다. (옵션)

const items1 = [1, 2, 3, 4];

// items[1]부터 2개의 요소를 제거하고 제거된 요소를 배열로 반환
const res1 = items1.splice(1, 2);

// 원본 배열이 변경된다.
console.log(items1); // [ 1, 4 ]
// 제거한 요소가 배열로 반환된다.
console.log(res1);   // [ 2, 3 ]

const items2 = [1, 2, 3, 4];

// items[1]부터 2개의 요소를 제거하고 그자리에 새로운 요소를 추가한다. 제거된 요소가 반환된다.
const res2 = items.splice(1, 2, 20, 30);

// 원본 배열이 변경된다.
console.log(items2); // [ 1, 20, 30, 4 ]
// 제거한 요소가 배열로 반환된다.
console.log(res2);   // [ 2, 3 ]

참고
자바스크립트 기본
유사 배열 객체와 배열의 차이
Array.from()

profile
작은 성취들이 모여 큰 결과를 만든다고 믿으며, 꾸준함을 바탕으로 개발 역량을 키워가고 있습니다

0개의 댓글