Programming Language/JavaScript

[JavaScript]자바스크립트의 배열 Array - 생성, 요소 참조 & 추가 & 갱신 & 삭제

영벨롭 2022. 5. 26. 18:58

[ 자바스크립트의 배열 ]

const arr = ["apple", "banana", "orange"];

 

 배열은 여러 개의 값을 순차적으로 나열한 자료구조입니다.

 

 배열이 가지고 있는 각각의 값을 '요소 element' 라고 부르며, 자바스크립트의 모든 값(원시값, 객체, 배열, 함수 등)은 배열의 요소가 될 수 있습니다. 

 

 배열의 인덱스는 다른 프로그래밍 언어들과 같이 zero based 인덱스로, 0부터 시작합니다. 

 

 사실, 자바스크립트에 배열이라는 타입은 존재하지 않습니다!

 

 배열은 객체 타입이지만, 일반 객체와는 구별되는 특징이 있습니다. 

 

 배열은 객체와 달리 값의 순서length 프로퍼티를 갖고 있기 때문에 순차적으로 요소를 접근할 수 있다는 장점이 있습니다. 

 

  객체 배열
구조 프로퍼티 키와 프로퍼티 값 인덱스와 요소
값의 참조 프로퍼티 키 인덱스
값의 순서 X O
length 프로퍼티 X O
// 배열
const arr = ["apple", "banana", "orange"];

// 객체
const obj = {
  fruit: 'apple',
  color: 'red'
}

console.log(typeof arr, arr);
console.log(typeof obj, obj);
console.log(arr[0]);
console.log(obj['fruit']);

 

 

 

 

 

[ length 프로퍼티 & 희소배열 ]

 

★ 일반 배열 vs 자바스크립트 배열

 자료구조에서 말하는 일반적인 배열은 동일한 크기의 메모리 공간이 연속적으로 나열된 자료구조를 말합니다. 이때의 배열의 요소들은 동일한 타입을 가지며 서로 연속적으로 인접해 있어야 하는데, 이러한 배열을 밀집 배열이라고 합니다. 

 

 밀집 배열의 요소를 검색(선형)할 때의 시간 복잡도는 O(N)이고, 요소를 삽입하거나 삭제하는 경우에도 요소들을 재배치해야한다는 단점이 있죠?

 

 자바스크립트의 배열은 각 요소의 메모리 공간이 동일한 크기가 아니어도 되며(타입이 다양할 수 있음) 연속적으로 이어져 있지 않을 수도 있습니다.

 

  일반적인 배열 자바스크립트의 배열
장점 인덱스로 요소에 빠르게 접근 가능 특정 요소를 검색/삽입/삭제하는 경우 일반 배열보다 빠름
단점 특정 요소를 검색/삽입/삭제 하는 경우 비효율적 해시 테이블로 구현된 객체이므로, 인덱스로 요소에 접근하는 경우 느림

 

 

★ length 프로퍼티

 length 프로퍼티는 배열의 요소의 개수, 즉 배열의 길이를 나타내는 0 이상의 정수 값을 가집니다.

 

 length 프로퍼티의 최댓값은 2^32 - 1 입니다. 즉, 배열의 요소는 최대 2^23 - 1 개 가질 수 있겠죠?

const arr = ["apple", "banana", "orange"];

console.log(arr.length)  // 3

 

 length 프로퍼티는 명시적으로 값을 재할당할 수 있는데요.

 

 만약 실제 배열의 길이보다 length 프로퍼티에 작은 값을 할당하게 되면, 배열의 길이가 줄어들게 됩니다.

const arr = ["apple", "banana", "orange"];

arr.length = 1;

console.log(arr.length, arr)   // 1 ["apple"]

 

 만약 실제 배열의 길이보다 큰 값을 할당하게 되면, length 프로퍼티의 값은 변경되지만, 실제 배열에는 아무런 변화가 없습니다. 값 없이 비어 있는 요소를 위한 메모리 공간을 확보하지도 않을 뿐더러 빈 요소를 생성하지도 않습니다. 

 

const arr = ["apple", "banana", "orange"];

arr.length = 5;

console.log(arr.length, arr)  // 5 ["apple", "banana", "orange", empty * 2]

 

 

★ 희소 배열

 밀집 배열과 반대로 배열의 요소가 연속적으로 이어져 있지 않는 배열을 희소 배열이라고 합니다. 

 

 희소 배열의 length와 배열 요소의 개수는 일치하지 않고, 희소 배열의 length는 배열의 실제 요소 개수보다 언제나 큽니다.희소 배열은 배열의 기본 개념과도 맞지 않아 성능에도 좋지 않은 영향을 주어 사용하지 않는 것이 좋습니다!

 

 자바스크립트 엔진은 요소의 타입이 일치하는 배열을 생성할 때 일반적인 의미의 배열처럼 연속된 메모리 공간을 확보합니다. 때문에 배열의 요소들을 같은 타입으로 넣어주는 것이 최선의 방법이라고 할 수 있습니다. 

 

// 희소 배열

const arr = [, 1, , 3]

console.log(arr.length, arr)   // 4, [empty, 1, empty, 3]

 

 

 

[ 배열 생성 ]

★ 배열 리터럴

 배열 생성의 가장 일반적이고 간편한 방식입니다. 

// 배열 리터럴
const arr = [1, 2, 3, 4, 5]

 

★ Array 생성자 함수 

 new Array() 형태로 생성하며, 인수의 개수에 따라 다르게 동작하는 것을 주의하세요!

 

// 1. 인수가 정수인 숫자 1개 일 때
// -> length 프로퍼티 값이 인수인 배열 생성
const arr1 = new Array(10);

// 2. 인수가 2개 이상이거나, 숫자가 아닐 경우
// -> 인수를 요소로 갖는 배열 생성
const arr2 = new Array(1, 2, 3);

// 3. 인수가 없는 경우
// -> 빈 배열 생성
const arr3 = new Array();

console.log(arr1.length, arr1);     // 10 [empty * 10]
console.log(arr2.length, arr2);     // 3 [1, 2, 3]
console.log(arr3.length, arr3);     // 0 []

 

 

★ Array.of

ES6 에서 도입되었으며, 전달된 인수를 요소로 갖는 배열을 생성합니다. 

const arr = Array.of(1, 2, 3);

 

 

★ Array.from

ES6 에서 도입되었으며 유사 배열 객체 또는 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환합니다. 

// 이터러블 객체
const arr1 = Array.from('hello');
// 유사배열 객체
const arr2 = Array.from({length: 3, 0: 'a', 1: 'b', 2: 'c'})

console.log(arr1);    // ['h', 'e', 'l', 'l', 'o']
console.log(arr2);    // ['a', 'b', 'c']

 

 두 번째 인수로는 콜백함수를 전달할 수도 있습니다. 첫 번째 인수에 의해 생성된 배열의 요소값과 인덱스가 콜백함수에 첫 번째, 두 번째 인수로 전달되어, 콜백 함수의 반환값으로 구성된 배열을 반환합니다. 

 

const arr1 = Array.from('hello', (el, idx) => {
  return el + `, idx: ${idx}`;
});
const arr2 = Array.from({length: 3, 0: 'a', 1: 'b', 2: 'c'}, (el, idx) => {
  return idx + el;
})
const arr3 = Array.from({length: 2}, (_, idx) => idx)

console.log(arr1);   // ['h, idx: 0', 'e, idx: 1', 'l, idx: 2', 'l, idx: 3', 'o, idx: 4']
console.log(arr2);   // ['0a', '1b', '2c']
console.log(arr3);   // [0, 1]

 

 

[ 배열의 요소 ]

★ 요소 참조

 배열의 요소를 참조할 때는 대괄호 [ ] 표기법을 사용합니다. 

 

 만약 인덱스의 값의 0보다 작거나 length 보다 크다면 존재하지 않는 요소를 참조하는 것이므로 undefined 가 반환됩니다. 

 

const arr = [1, 2, 3, 4, 5];

const a = arr[1];   // 2
const b = arr[100];  // undefined
const c = arr[-1];   // undefined

 

 

★ 요소 추가 / 갱신

 객체와 마찬가지로 배열에도 요소를 동적으로 추가할 수 있습니다. 

 

 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가됩니다. 이때 length 프로퍼티의 값은 자동으로 갱신됩니다. 

 

 만약 현재 length 프로퍼티 값보다 큰 인덱스로 새로운 요소를 추가하면 희소 배열이 됩니다. 

 

 이미 요소가 존재하는 요소에 값을 재할당하면 요소가 갱신되고, 이때 length 프로퍼티 값에는 영향을 주지 않습니다. 

 

const arr = [1, 2, 3, 4, 5];

// 요소 추가
arr[5] = 6;
console.log(arr);   // [1, 2, 3, 4, 5, 6]

// 요소 갱신
arr[0] = 0;
console.log(arr);   // [0, 2, 3, 4, 5, 6]

// 요소 추가(희소 배열)
arr[10] = 10;
console.log(arr);   // [0, 2, 3, 4, 5, 6, empty * 4, 10]

 

 

★ 요소 삭제

 요소를 삭제할 때에는 delete 연산자를 사용할 수 있습니다. 이때 배열은 희소 배열이 되며 length 프로퍼티 값은 변하지 않습니다. 

 

 희소배열을 만들지 않으면서 배열의 특정 요소를 삭제하기 위해선 Array.prototype.splice 메서드를 사용합니다. 

 

 splice(idx, n) 은 idx 번째 요소부터 n 개를 삭제합니다. 

 

const arr = [1, 2, 3, 4, 5];

delete arr[1];
console.log(arr.length, arr);  // 5 [1, empty, 3, 4, 5]

arr.splice(1, 2);
console.log(arr.length, arr);  // 3 [1, 4, 5]

 

 

반응형