쑤쑤_CS 기록장

28. 배열 본문

IT 지식 기록/JavaScript 정리

28. 배열

(╹◡╹)_ 2020. 12. 25. 09:35
728x90

배열(array)

  • 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다.
  • 자바스크립트에서 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.
  • Array 생성자로 생성된 Array 타입의 객체이며, 프로토타입 객체는 Array.prototype이다.

#1. 배열의 생성

#1.1 배열 리터럴

  • 0개 이상의 값을 쉼표로 구분하여 대괄호([])로 묶는다.
  • 존재하지 않는 요소에 접근하면 undefined 반환한다.
const emptyArr = [];

console.log(emptyArr[1]); // undefined
console.log(emptyArr.length); // 0

const arr = [
  'zero', 'one', 'two', 'three', 'four',
  'five', 'six', 'seven', 'eight', 'nine'
];

console.log(arr[1]);      // 'one'
console.log(arr.length);  // 10
console.log(typeof arr);  // object

 

<배열 리터럴과 객체 리터럴의 차이>

- 배열 리터럴은 객체 리터럴과 달리 프로퍼티명이 없고 각 요소의 값만이 존재한다.

- 객체는 프로퍼티 값에 접근하기 위해 대괄호 표기법 또는 마침표 표기법을 사용하며 프로퍼티명을 키로 사용한다.

- 배열은 요소에 접근하기 위해 대괄호 표기법만을 사용하며 대괄호 내에 접근하고자 하는 요소의 인덱스를 넣어준다. 인덱스는 0부터 시작한다.

- 두 객체의 근본적 차이는 배열 리터럴 arr의 프로토타입 객체는 Array.prototype이지만 객체 리터럴 obj의 프로토타입 객체는 Object.prototype라는 것이다.

 

#1.2 Array() 생성자 함수

  • 배열 리터럴 방식으로 일반적으로 생성하고, 내장 함수 Array()도 생성자 함수로 동작한다.
  • Array.prototype.constructor 프로퍼티로 접근
  • 매개변수의 갯수에 따라 다르게 동작
    • 매개변수가 1개이고 숫자인 경우 매개변수로 전달된 숫자를 length 값으로 가지는 빈 배열을 생성한다.
    • 그 외의 경우 매개변수로 전달된 값들을 요소로 가지는 배열을 생성한다.
const arr = new Array(2);
console.log(arr); // (2) [empty × 2]

const arr = new Array(1, 2, 3);
console.log(arr); // [1, 2, 3]

 

#2. 배열 요소의 추가와 삭제

#2.1 배열 요소의 추가

  • 동적으로 요소를 추가할 수 있다.

  • 순서에 맞게 값을 할당할 필요는 없고, 인덱스를 사용하여 필요한 위치에 값을 할당한다.

  • 배열의 길이는 마지막 인덱스를 기준으로 산정된다.
  • 값이 할당되지 않은 인덱스 위치의 요소는 생성되지 않는다

  • 존재하지 않는 요소를 참조하면 undefined가 반환된다.

const arr = [];
console.log(arr[0]); // undefined

arr[1] = 1;
arr[3] = 3;

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

 

#2.2 배열 요소의 삭제

  • 배열 요소를 삭제하기 위해 delete 연산자를 사용 (이때 length에는 변함이 없다.)

  • 해당 요소를 완전히 삭제하여 length에도 반영되게 하기 위해서는 Array.prototype.splice 메소드를 사용한다.

const numbersArr = ['zero', 'one', 'two', 'three'];

// 요소의 값만 삭제된다
delete numbersArr[2]; // (4) ["zero", "one", empty, "three"]
console.log(numbersArr);

// 요소 값만이 아니라 요소를 완전히 삭제한다
// splice(시작 인덱스, 삭제할 요소수)
numbersArr.splice(2, 1); // (3) ["zero", "one", "three"]
console.log(numbersArr);

 

 

#3. 배열의 순회

배열의 순회에는 forEach 메소드, for 문, for…of 문을 사용하는 것이 좋다.

const arr = [0, 1, 2, 3];
arr.foo = 10;

for (const key in arr) {
  console.log('key: ' + key, 'value: ' + arr[key]);
}
// key: 0 value: 0
// key: 1 value: 1
// key: 2 value: 2
// key: 3 value: 3
// key: foo value: 10 => 불필요한 프로퍼티까지 출력

arr.forEach((item, index) => console.log(index, item));

for (let i = 0; i < arr.length; i++) {
  console.log(i, arr[i]);
}

for (const item of arr) {
  console.log(item);
}

#4. Array Property

#4.1 Array.length

  • 요소의 개수(배열의 길이)를 나타낸다.

  • 배열 요소의 개수와 length 프로퍼티의 값이 반드시 일치하지는 않는다.
  • 현재 length 프로퍼티 값보다 더 큰 인덱스로 요소를 추가하면, length 프로퍼티의 값이  (가장 큰 인덱스 + 1 ) 값으로 증가한다.

  • 값을 명시적으로 변경 가능하다.

희소배열

: 배열 요소의 개수와 length 프로퍼티의 값이 일치하지 않는 배열. 요소가 연속적이지 않은 배열

- 배열의 요소 개수보다 length 프로퍼티의 값이 항상 크다.

- 일반 배열보다 느리며 메모리를 낭비하는 특징이 있다.

 

#5. Array Method

메소드에 따라 this(원본 배열)이 수정되는 경우와 아닌 경우가 있다

 

#5.1 Array.isArray(arg: any): boolean

  • 주어진 인수가 배열이면 true 반환
  • 주어진 인수가 배열이 아니면 false 반환
// true
Array.isArray([]);
Array.isArray([1, 2]);
Array.isArray(new Array());

// false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(1);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);

 

#5.2 Array.form

  • 유사 배열 객체 또는 이터러블 객체(iterable object)를 변환하여 새로운 배열을 생성

// 문자열은 이터러블이다.
const arr1 = Array.from('Hello');
console.log(arr1); // [ 'H', 'e', 'l', 'l', 'o' ]

// 유사 배열 객체를 새로운 배열을 변환하여 반환한다.
const arr2 = 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 ]

 

#5.3 Array.of

  • 전달된 인수를 요소로 갖는 배열을 생성

// 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
const arr1 = Array.of(1);
console.log(arr1); // // [1]

const arr2 = Array.of(1, 2, 3);
console.log(arr2); // [1, 2, 3]

const arr3 = Array.of('string');
console.log(arr3); // 'string'

 

#5.4 Array.prototype.indexOf(searchElement: T, fromIndex?: number): number

  • 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환
  • 중복되는 요소가 있는 경우 → 첫번째 인덱스를 반환
  • 해당하는 요소가 없는 경우 → -1을 반환

#5.5 Array.prototype.concat(…items: Array<T[] | T>): T[]

  • 인수로 전달된 값들을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환
    • 인수로 배열이 전달된 경우 배열을 해체하여 새로운 배열의 요소로 추가

#5.6 Array.prototype.join(separator?: string): string

  • 원본 배열의 모든 요소를 문자열로 변환 후, 인수로 전달받은 값(=구분자) 로 연결한 문자열을 반환
  • 구분자(seperator)는 생략 가능하며 기본 구분자는 ,

#5.7 Array.prototype.push(…items: T[]): number

  • 인수로 전달받은 모든 값을 원본 배열의 마지막에 요소로 추가하고 변경된 length 값을 반환

  • 원본 배열을 직접 변경한다.

<push vs concat 메소드>

  • push 메소드는 원본 배열을 직접 변경하지만 concat 메소드는 원본 배열을 변경하지 않고 새로운 배열을 반환한다.
  • 인수로 전달받은 값이 배열인 경우, push 메소드는 배열을 그대로 원본 배열의 마지막 요소로 추가하지만 concat 메소드는 배열을 해체하여 새로운 배열의 마지막 요소로 추가한다.

#5.8 Array.prototype.pop(): T | undefined

  • 원본 배열의 마지막 요소를 제거하고 제거한 요소를 반환
  • 원본 배열이 빈 배열이면, undefined 반환
  • 원본 배열이 변경된다

스택(stack)

  • pop메소드와 push메소드를 사용하여 쉽게 구현할 수 있다.
  • 마지막에 넣은 데이터를 먼저 꺼내는 후입 선출(LIFO, last in last out)
  • 가장 마지막에 넣은 최신 데이터를 취득한다.
  • 데이터를 밀어 넣는 것을 푸시, 스택에서 꺼대는 것을 팝 이라 한다.

#5.9 Array.prototype.reverse(): this

  • 배열 요소의 순서를 반대로 변경
  • 원본 배열이 변경되어 반환된다

#5.10 Array.prototype.shift(): T | undefined

  • 배열에서 첫 요소를 제거한 요소를 반환
  • 빈 배열이면 undefined 반환
  • 원본 배열이 변경된다.
  • shift는 push와 함께 배열을 큐(FIFO: First In First Out)처럼 동작하게 한다.
const arr = [];

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

arr.shift(); // [2, 3]
arr.shift(); // [3]
arr.shift(); // []
const a = ['a', 'b', 'c'];
const c = a.pop();

// 원본 배열이 변경된다.
console.log(a); // a --> ['a', 'b']
console.log(c); // c --> 'c'

#5.11 Array.prototype.slice(start=0, end=this.length): T[]

  • 인자로 지정된 부분을 복사하여 반환

  • 원본 배열은 변경 안됨

  • 첫번째 매개변수 start에 해당하는 인덱스를 갖는 요소부터 매개변수 end에 해당하는 인덱스를 가진 요소 전까지 복사
const items = ['a', 'b', 'c'];

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

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

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

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

res = items.slice(-2);
console.log(res);  // [ 'b', 'c' ]

// 모든 요소를 반환 (= 복사본(shallow copy) 생성)
res = items.slice();
console.log(res);  // [ 'a', 'b', 'c' ]

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

 

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

  • 기존 배열의 요소를 제거하고 그 위치에 새로운 요소를 추가
  • 배열 중간에 새로운 요소를 추가할 때도 사용

매개변수

  • start
    : 배열에서의 시작 위치이다. start 만을 지정하면 배열의 start부터 모든 요소를 제거한다.

  • deleteCount
    : 시작 위치(start)부터 제거할 요소의 수이다. deleteCount가 0인 경우, 아무런 요소도 제거되지 않는다.

  • items 
    : 삭제한 위치에 추가될 요소들이다. 만약 아무런 요소도 지정하지 않을 경우, 삭제만 한다.

728x90
Comments