배열 Array

·2023년 2월 27일
0

배열은 순서가 있는 컬렉션을 저장할 때 쓰는 자료구조 입니다.
배열을 사용하면 새로운 프로퍼티를 기존 프로퍼티 ‘사이에’ 끼워 넣는 것이 가능합니다.

순서가 있는 컬렉션을 다뤄야 할 때 객체를 사용하면 순서와 관련된 메서드가 없어 그다지 편리하지 않습니다.


배열 선언

대부분 두 번째 대괄호 방법으로 선언하기 때문에,
new Array()은 설명하지 않겠습니다.

<script>
let arr = new Array();
let arr = [];
</script>

대괄호 안에 초기 요소를 넣어주는 것도 가능합니다.

<script>
let fruits = ["사과", "오렌지", "자두"];
</script>

각 배열 요소엔 0부터 시작하는 숫자(인덱스)가 매겨져 있습니다. 이 숫자들은 배열 내 순서를 나타냅니다.
배열 내 특정 요소를 얻고 싶다면 대괄호 안에 순서를 나타내는 숫자인 인덱스를 넣어주면 됩니다.

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

alert( fruits[0] ); // 사과
alert( fruits[1] ); // 오렌지
alert( fruits[2] ); // 자두
</script>

요소를 수정하고, 추가할 수도 있습니다.

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

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

length를 사용하면 배열에 담긴 요소가 몇 개인지 알아낼 수 있습니다.

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

alert( fruits.length ); // 3
</script>

alert를 사용해 요소 전체를 출력하는 것도 가능합니다.

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

alert( fruits ); // 사과,오렌지,자두
</script>

배열 요소의 자료형엔 제약이 없습니다.

<script>
// 요소에 여러 가지 자료형이 섞여 있습니다.
let arr = [ '사과', { name: '조두찌' }, true, function() { alert('안녕하세요.'); } ];

// 인덱스가 1인 요소(객체)의 name 프로퍼티를 출력합니다.
alert( arr[1].name ); // 조두찌

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

pop·push와 shift·unshift

선입선출: 큐(queue)는 배열을 사용해 만들 수 있는 대표적인 자료구조로, 배열과 마찬가지로 순서가 있는 컬렉션을 저장하는 데 사용합니다.
자주 쓰이는 자료구조입니다.

큐에서 사용하는 주요 연산

  • push – 맨 끝에 요소를 추가합니다.
  • shift – 제일 앞 요소를 꺼내 제거한 후 남아있는 요소들을 앞으로 밀어줍니다.

--
배열은 큐 이외에
후입선출: 스택(stack)이라 불리는 자료구조를 구현할 때도 쓰입니다.
스택은 '한쪽 끝’에 요소를 더하거나 뺄 수 있게 해주는 자료구조입니다.

스택에서 사용하는 연산

  • push – 요소를 스택 끝에 집어넣습니다.
  • pop – 스택 끝 요소를 추출합니다.

이렇게 처음이나 끝에 요소를 더하거나 빼주는 연산을 제공하는 자료구조를 컴퓨터 과학 분야에선 데큐(deque, Double Ended Queue)라고 부릅니다.

--

pop과 push는 배열 끝에 무언가를 해주는 메서드입니다.
pop

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

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

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

push

  • 배열 끝에 요소를 추가합니다.
<script>
let fruits = ["사과", "오렌지"];

fruits.push("배");

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

--
shift와 unshift는 배열 앞에 무언가를 해주는 메서드입니다.
shift

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

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

alert( fruits ); // 오렌지,배
</script>

unshift

  • 배열 앞에 요소를 추가합니다.
<script>
let fruits = ["오렌지", "배"];

fruits.unshift('사과');

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

push와 unshift는 요소 여러 개를 한 번에 더해줄 수도 있습니다.

<script>
let fruits = ["사과"];

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

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

배열은 특별한 종류의 "객체" 입니다.

배열은 객체와 마찬가지로 참조를 통해 복사됩니다.

<script>
let fruits = ["바나나"]

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

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

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

alert( fruits ); // 바나나,배 - 요소가 두 개가 되었습니다.

</script>

배열은 객체이므로 예시처럼 원하는 프로퍼티를 추가해도 문제가 발생하지 않습니다.
하지만, 배열을 '순서가 있는 자료의 컬렉션’처럼 다루지 않고 일반 객체처럼 다루면 배열의 연산속도를 높혀주 최적화 기법 등이 동작하지 않습니다.

  • 예시
<script>
let fruits = []; // 빈 배열을 하나 만듭니다.

fruits[99999] = 5; // 배열의 길이보다 훨씬 큰 숫자를 사용해 프로퍼티를 만드는 경우

fruits.age = 25; // 숫자가 아닌 값을 프로퍼티 키로 사용하는 경우

arr[0] arr[1000] // 인덱스만 추가하고 그사이에 아무런 요소도 없는 경우

arr[1000] arr[999] // 요소를 역순으로 채우는 경우
</script>

임의의 키를 사용해야 한다면 배열보단 일반 객체 {}가 적합한 자료구조일 확률이 높습니다.

  • 종합 예시
<script>
var greenArr = ["교대", "방배", "강남"];
var yellowArr = ["미금", "정자", "수서"];

greenArr.splice(2, 1, "서초", "역삼"); // 인덱스번호 2부터(포함) 1개 삭제. 강남만 삭제
console.log(greenArr); // 교대, 방배, 서초, 역삼

var data1 = yellowArr.pop(); // 수서를 떼서 data1에 저장
var data2 = yellowArr.shift(); // 미금을 떼서 data2에 저장

console.log(yellowArr); // 현재 yellowArr는 수서와 미금이 제거 됐기 때문에 정자만 남아있다.
yellowArr.push(data2); // 정자 뒤에 미금(data2) 밀어넣기
console.log(yellowArr); // 정자, 미금

yellowArr.unshift(data1); // 정자, 미금(yellowArr) 앞에 수서(data1)를 끼우기
console.log(yellowArr); // 수서, 정자, 미금
</script>

배열에 적용할 수 있는 반복문

  1. for문
    배열을 순회할 때 쓰는 가장 오래된 방법입니다. 순회시엔 인덱스를 사용합니다.
<script>
let arr = ["사과", "오렌지", "배"];

for (let i = 0; i < arr.length; i++) {
  alert( arr[i] );
}
</script>
  1. for..of
    for..of를 사용하면 현재 요소의 인덱스는 얻을 수 없고 값만 얻을 수 있습니다. 이 정도 기능이면 원하는 것을 충분히 구현할 수 있고 문법도 짧기 때문에 배열의 요소를 대상으로 반복 작업을 할 때 유용합니다.
<script>
let fruits = ["사과", "오렌지", "자두"];

// 배열 요소를 대상으로 반복 작업을 수행합니다.
for (let fruit of fruits) {
  alert( fruit ); // 사과 오렌지 자두
}
</script>

❌for..in 반복문
1. 모든 프로퍼티를 대상으로 순회합니다. 키가 숫자가 아닌 프로퍼티도 순회 대상에 포함됩니다. ‘필요 없는’ 프로퍼티들이 문제를 일으킬 가능성이 생깁니다.
2. 반복문은 배열이 아니라 객체와 함께 사용할 때 최적화되어 있어서 배열에 사용하면 객체에 사용하는 것 대비 10~100배 정도 느립니다.


length 프로퍼티

배열에 무언가 조작을 가하면 length 프로퍼티가 자동으로 갱신됩니다.
length 프로퍼티는 배열 내 요소의 개수가 아니라 가장 큰 인덱스 + 1 입니다.

따라서 배열에 요소가 하나뿐이지만, 이 요소의 인덱스가 아주 큰 정수라면 배열의 length 프로퍼티도 아주 커집니다.

<script>
let fruits = [];
fruits[123] = "사과"; // 배열을 이렇게 사용하지 않도록 합시다.

alert( fruits.length ); // 124
</script>

--
length 프로퍼티는 쓰기가 가능합니다.

length의 값을 수동으로 증가시키면 아무 일도 일어나지 않습니다.
그런데 값을 감소시키면 배열이 잘립니다. 잘린 배열은 다시 되돌릴 수 없습니다.

<script>
let arr = [1, 2, 3, 4, 5];

arr.length = 2; // 요소 2개만 남기고 잘라봅시다.
alert( arr ); // [1, 2]

arr.length = 5; // 본래 길이로 되돌려 봅시다.
alert( arr[3] ); // undefined: 삭제된 기존 요소들이 복구되지 않습니다.
</script>

이런 특징을 이용하면 arr.length = 0;을 사용해 간단하게 배열을 비울 수 있습니다.


다중 배열

배열 역시 배열의 요소가 될 수 있습니다. 이런 배열을 가리켜 다차원 배열(multidimensional array)이라 부릅니다.
다차원 배열은 행렬을 저장하는 용도로 쓰입니다.

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

alert( matrix[1][1] ); // 5. 1번 요소의 1번 프로퍼티이기 때문
</script>

toString

배열을 문자열로 반환해주는 메서드

<script>
let arr = [1, 2, 3];

alert( arr ); // 1,2,3
alert( String(arr) === '1,2,3' ); // true
</script>

--
이항 덧셈 연산자 "+"는 피연산자 중 하나가 문자열인 경우 나머지 피연산자도 문자열로 변환합니다.
+를 사용할 때 배열은 문자열과 동일하게 동작합니다.

<script>
alert( [] + 1 ); // "1"
alert( [1] + 1 ); // "11"
alert( [1,2] + 1 ); // "1,21"
// 위 아래 동일하게 동작합니다.
alert( "" + 1 ); // "1"
alert( "1" + 1 ); // "11"
alert( "1,2" + 1 ); // "1,21"
</script>
profile
저녁놀 마을 사람

0개의 댓글

관련 채용 정보