글 작성자: 망고좋아
반응형

 

배열

  • 배열이란 순서가 있는 컬렉션을 저장할 때 쓰는 자료구조이다.

 

 

배열 선언

let arr = new Array();
let arr = []; // 대부분 이 방법을 사용해서 선언한다.
let fruits = ["사과", "오렌지", "자두"]; // 초기 요소를 넣을 수 있다.

 

배열 수정

fruits[2] = '배'; // 배열이 ["사과", "오렌지", "배"]로 바뀜

 

새로운 요소 추가

fruits[3] = '레몬'; // 배열이 ["사과", "오렌지", "배", "레몬"]으로 바뀜

 

배열의 길이 알아내기 :: length

let fruits = ["사과", "오렌지", "자두"];

alert( fruits.length ); // 3
// 요소에 여러 가지 자료형이 섞여 있다.
let arr = [ '사과', { name: '이보라' }, true, function() { alert('안녕하세요.'); } ];

// 인덱스가 1인 요소(객체)의 name 프로퍼티를 출력한다.
alert( arr[1].name ); // 이보라

// 인덱스가 3인 요소(함수)를 실행한다.
arr[3](); // 안녕하세요.

 

🔔 trailing 쉼표

  • 배열 마지막 요소는 객체와 마찬가지고 쉼표로 끝날 수 있다.
  • 이렇게 사용하면 요소를 넣고 빼기가 쉬워진다.

 

 

pop·push와 shift·unshift

  • 큐(Queue)는 배열을 사용해 만들 수 있는 대표적인 자료구조
  • 순서가 있는 컬렉션을 저장하는 데 사용
  • push
    • 맨 끝에 요소를 추가한다.
  • shift
    • 제일 앞 요소를 꺼내 제거한 후 남아 있는 요소들을 앞으로 밀어준다.

 

 

스택

  • 스택은 '한쪽 끝’에 요소를 더하거나 뺄 수 있게 해주는 자료구조이다.
  • 따라서 가장 나중에 집어넣은 요소가 가장 먼저 나온다고 해서 후입 선출(Last-In-First-Out, LIFO)이라고 부른다.

 

스택에서 사용하는 연산

  • push : 요소를 스택 끝에 집어넣는다.
  • pop : 스택 끝 요소를 추출한다.

 

 

  • 큐를 사용하면 먼저 집어넣은 요소가 먼저 나오기 때문에 큐는 선입선출(First-In-First-Out, FIFO) 자료구조라고 부른다.
  • 자바스크립트 배열을 사용하면 큐와 스택 모두 만들 수 있다.
  • 이렇게 처음이나 끝에 요소를 더하거나 빼주는 연산을 제공하는 자료구조를 데큐(deque, Double Ended Queue)라고 부른다.

 

 

배열 끝에 무언가를 더해주는 메서드

pop

  • 배열 끝 요소를 제거하고, 제거한 요소를 반환해준다.
let fruits = ["사과", "오렌지", "배"];

alert( fruits.pop() ); // 배열에서 "배"를 제거하고 제거된 요소를 얼럿창에 띄웁니다.

alert( fruits ); // 사과,오렌지

 

push

  • 배열 끝에 요소를 추가해준다.
let fruits = ["사과", "오렌지"];

fruits.push("배");

alert( fruits ); // 사과,오렌지,배

 

 

배열 앞에 무언가를 더해주는 메서드

shift

  • 배열 앞 요소를 제거하고, 제거한 요소를 반환해준다.
let fruits = ["사과", "오렌지", "배"];

alert( fruits.shift() ); // 배열에서 "사과"를 제거하고 제거된 요소를 얼럿창에 띄웁니다.

alert( fruits ); // 오렌지,배

 

unshift

  • 배열 앞에 요소를 추가해준다.
let fruits = ["오렌지", "배"];

fruits.unshift('사과');

alert( fruits ); // 사과,오렌지,배
  • 두 개 모두 여러 개의 요소를 한 번에 더해줄 수 있다.
let fruits = ["사과"];

fruits.push("오렌지", "배");
fruits.unshift("파인애플", "레몬");

// ["파인애플", "레몬", "사과", "오렌지", "배"]
alert( fruits );

 

 

배열의 내부 동작 원리

  • 배열은 순자형 키를 사용함으로써 객체 기본 기능 이외에도 순서가 있는 컬렉션을 제어하게 해주는 특별한 메서드를 제공한다.
  • 배열은 7가지 원시 자료형에 해당되지 않고, 원시 자료형이 아닌 객체형에 속하기 때문에 객체처럼 동작한다.
let fruits = ["바나나"]

let arr = fruits; // 참조를 복사함(두 변수가 같은 객체를 참조)

alert( arr === fruits ); // true

arr.push("배"); // 참조를 이용해 배열을 수정합니다.

alert( fruits ); // 바나나,배 - 요소가 두 개가 되었습니다.
  • 배열의 요소를 인접한 메모리 공간에 차례로 저장해 연산 속도를 높인다.

 

 

성능

  • pushpop은 빠르지만 shiftunshift는 느리다.

 

배열 앞에 무언가를 빼고 더해주는 메서드가 느린 이유는?

  • shift 연산은 아래 3가지 동작을 모두 수행해야 된다..
    1. 인덱스가 0인 요소를 제거한다
    2. 모든 요소를 왼쪽으로 이동 -> 인덱스 10, 21로 변화
    3. length 프로퍼티 값을 갱신

  • 또한, 배열에 요소가 많으면 요소가 이동하는 데 걸리는 시간이 길어지고 메모리 관련 연산도 많아진다. unshift도 유사하게 동작을 수행한다, 그래서 느리다.

 

반면 pushpop는 배열 뒤에서만 행동이 이루어지기 때문에 속도가 빠르다.

  • pop 메서드는 요소를 옮기지 않으므로 각 요소는 기존 인덱스를 그대로 유지한다. -> 속도가 빠른 이유, push 또한 유사한 동작을 수행한다.

 

 

반복문

  • for문은 배열을 순회할 때 쓰는 가장 오래된 방법이다.
let arr = ["사과", "오렌지", "배"];

for (let i = 0; i < arr.length; i++) {
  alert( arr[i] );
}
// 출력 : 사과, 오렌지, 자두

// for..of
// 인덱스를 얻을 수 없다.
let fruits = ["사과", "오렌지", "자두"];

// 배열 요소를 대상으로 반복 작업을 수행한다.
for (let fruit of fruits) {
  alert( fruit );
}

 

for..in => 배열에 사영하면 문제 발생, 권장 안 함

  • 배열은 객체형에 속하므로 for..in도 사용 가능하다.
  • 모든 프로퍼티를 대상으로 순회한다. 키가 숫자가 아닌 프로퍼티도 순회대상에 포함되기 때문에 문제가 발생될 수 있다.
let arr = ["사과", "오렌지", "배"];

for (let key in arr) {
  alert( arr[key] ); // 사과, 오렌지, 배
}

 

 

length 프로퍼티

  • 배열에 무언가 조작을 가하면 length 프로퍼티가 자동으로 갱신된다.
  • length 프로퍼티는 배열 내 요소의 개수가 아니라 가장 큰 인덱스에 1을 더한 값이다.
// 이렇게 사용하지 말자....!!
let fruits = [];
fruits[123] = "사과";

alert( fruits.length ); // 124
  • length 프로퍼티는 쓰기가 가능하다.
  • length의 값을 수동으로 증가시키면 아무 일도 일어나지 않지만, 값을 감소시키면 배열이 잘린다. 짧아진 배열은 다시 되돌리 수 없다.
let arr = [1, 2, 3, 4, 5];

arr.length = 2; // 요소 2개만 남기고 자르기.
alert( arr ); // [1, 2]

arr.length = 5;
alert( arr[3] ); // undefined: 삭제된 기존 요소들이 복구되지 않는다.
  • 이런 특징을 이용해 arr.length = 0;을 이용하면 배열을 간단하게 비울 수 있다.

 

 

다차원 배열

let matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

alert( matrix[1][1] ); // 5, 중심에 있는 요소

 

 

toString

  • 배열엔 toString 메서드가 구현되어 있어 이를 호출하면 요소를 쉼표로 구분한 문자열이 반환된다.
let arr = [1, 2, 3];

alert( arr ); // 1,2,3
alert( String(arr) === '1,2,3' ); // true
alert( [] + 1 ); // "1"
alert( [1] + 1 ); // "11"
alert( [1,2] + 1 ); // "1,21"
  • 배열엔 Symbol.toPrimitivevalueOf 메서드가 없다.
  • 문자열로의 형 변환이 일어나 []는 빈 문자열, [1]은 문자열 "1", [1,2]는 문자열 "1,2"로 변환된다.
alert( "" + 1 ); // "1"
alert( "1" + 1 ); // "11"
alert( "1,2" + 1 ); // "1,21"
  • 이항 덧셈 연산자 "+"는 피연산자 중 하나가 문자열인 경우 나머지 피연산자도 문자열로 변환된다.

 

 

📌 참고

반응형