[JS] 배열
배열은 하나의 변수 안에 여러 개의 데이터를 그룹화해서 저장하는 Javascript의 가장 기본적인 자료구조 입니다.
학습목표
- 배열을 이해하고 배열 데이터를 구성할 수 있다.
- 1차배열과 2차배열을 구분할 수 있다.
- 요구사항에 부합하는 결과값을 도출하기 위해 배열 데이터를 탐색할 수 있다.
- 요구사항에 따라 배열 데이터를 조작하여 새로운 자료구조를 생성할 수 있다.
#01. 배열의 이해
1) 배열의 필요성
학급의 성적표를 보고 각 학생별로 총점과 평균을 구해야 한다고 가정할 때,
이름 | 국어 | 영어 | 수학 |
---|---|---|---|
철수 | 92 | 81 | 77 |
영희 | 72 | 95 | 98 |
민혁 | 80 | 86 | 84 |
성적표가 아래와 같다면 3명씩 3과목이므로 총 9개의 변수가 필요할 것이다.
var kor1 = 92;
var kor2 = 71;
var kor3 = 80;
// ... 생략 ...
var math2 = 84;
var math3 = 98;
만약 30명의 학생에 대한 20과목에 대한 점수라고 가정한다면 생성해야 하는 변수가 더 증가하므로 프로그램은 좀 더 복잡해 질 것이다.
배열은 이러한 경우를 해소하기 위한 자바스크립트 자료구조의 하나로, 변수에 여러 개의 데이터를 그룹화해서 저장해 놓은 상태를 말한다.
2) 배열 생성하기
배열의 선언
Javascript는 변수의 특성이 값이 할당 될 때 결정되기 때문에 선언은 일반 변수와 동일하다.
즉, 할당하기 전까지는 숫자, 문자열, 배열 등의 구분이 없다.
let myArr;
배열의 할당
대괄호([]
)안에 포함할 값들을 데이터 타입의 구분 없이 콤마(,
)로 구분하여 나열한다.
선언과 할당이 나누어져 있는 경우 const
로 선언할 수 없다.
myArr = [1, 2, 3.14, true, false, "hello", "world"];
선언과 할당의 통합
let myArr = [1, 2, 3, 5, 7];
Array 클래스를 사용한 할당
new Array(...)
형식으로 생성한다.
let newArr1 = new Array("hello", "world", 1, 2, 3, true, false);
클래스는 아직 소개되지 않은 개념이므로 여기서는 명령어의 일종으로 받아들이시기 바랍니다.
Array 클래스 사용시 주의할 점
new Array()
로 배열을 생성할 때 ()
안에 숫자 값 하나만 명시되는 경우, 숫자 값 만큼의 빈 칸을 갖는 배열이 생성된다.
배열의 각 칸은 모두 정의되지 않은 값(undefined)로 할당된다.
3) 배열의 크기
배열이름.length
는 배열의 칸 수를 반환한다.
배열의 인덱스는 항상 0
부터 크기-1
까지 1씩 증가하면서 존재한다.
4) 배열의 원소에 접근하기
인덱스 번호를 활용한 접근
배열의 각 원소는 0부터 시작하는 일련번호를 부여 받는데, 이를 배열의 인덱스 라고 한다.
배열의 원소에 접근할 때는 인덱스 번호를 활용하여 접근해야 한다.
let myArr = [1, 2, 3.14, true, false, "hello", "world"];
console.log(myArr[0]);
console.log(myArr[2]);
console.log(myArr[4]);
console.log(myArr[6]);
존재하지 않는 원소의 값을 출력하고자 할 경우, 정의되어 있지 않으므로 undefined가 된다.
구조분해
아래와 같이 활용하면 배열의 각 원소가 순서대로 a, b, c에 나누어 저장된다.
let myArr2 = [100,200,300];
const [a, b, c] = myArr2;
원소 수보다 선언된 변수가 적을 경우 정의된 변수까지만 저장되고 할당될 변수가 정의되지 않은 원소(여기서는 300)는 버려진다.
let myArr3 = [100,200,300];
const [a, b] = myArr2;
원소 수보다 선언된 변수가 많을 경우 분리될 원소가 없는 변수(여기서는 d)는 undefined가 된다.
let myArr4 = [100,200,300];
const [a, b, c, d] = myArr4;
구조분해를 수행하고 나머지 원소를 별도의 배열에 저장해야 할 경우 ...
을 사용한다.
아래의 코드에서 a에 100이 저장되고 b에는 200이 저장된 후, rest는 [300,400,500]
형태의 배열이 된다.
let myArr5 = [100,200,300,400,500];
const [a, b, ...rest] = myArr5;
존재하지 않는 원소에 대한 접근
존재하지 않는 원소의 값을 출력할 경우 undefined가 출력된다.
const myArr6 = [1,2,3];
console.log(myArr6[4]); // undeifned
존재하지 않는 원소를 활용하여 연산을 처리할 경우 undefined를 활용한 연산이 되므로 그 결과는 NaN이 된다.
const myArr7 = [1,2,3];
let a = myArr7[4] + 1; // NaN
존재하지 않는 원소에 값을 할당할 경우 그 인덱스에 대한 값이 새로 생성된다. 만약 그 중간에 누락된 인덱스가 있다면 모두 undefined가 된다.
아래 코드에서 인덱스가 4인 원소가 생성되고 할당되지 않은 인덱스 3인 위치는 undefined가 됨
const myArr8 = [1,2,3];
myArr8[4] = 5;
5) 반복문을 통한 활용
기본 반복문의 활용
배열은 인덱스가 0부터 1씩 배열의 길이보다 작은 동안 순차적으로 증가한다는 특성이 있다.
반복문의 초기식을 0으로, 조건식을 길이보다 작은 동안, 증감식을 1씩 증가로 설정한 반복문과 함께 사용하는 것이 일반적이다.
이와 관련하여 다양한 예제 패턴들이 존재한다.
for~of
문
배열의 모든 원소를 순차적으로 탐색하여 선언된 변수에 자동 할당하는 반복문
아래 문법에서 선언된 v
에 myArr6
의 모든 원소가 순차적으로 할당된다.
이 반복문은 더 빠른 탐색 속도와 간결한 문법 표현을 제공하지만 현재 처리중인 원소에 대한 인덱스를 알 수는 없다.
const myArr9 = [1,2,3];
for (const v of myArr9) {
...
}
#02. 2차 배열
1차 배열의 각 원소가 다른 배열로 구성된 형태.
열의 개념만 존재하는 1차 배열에 행의 개념을 추가한 형태가 2차 배열 이다.
1) 2차 배열 생성하기
[]
를 사용하여 1차원을 표현하고 그 안에 다시 []
를 콤마로 구분하여 2차원을 구성한다.
const myArr10 = [ [ ... ], [...] ]
2) 2차 배열의 원소에 접근하기
2행 3열인 경우 행의 인덱스는 0부터 1까지, 열의 인덱스는 0부터 2까지 존재한다.
배열에 저장된 원소에 접근하기 위해서는 변수이름 뒤에 행, 열의 순서로 인덱스를 명시한다.
3) 2차 배열의 행, 열 크기 구하기
행의 크기
2차 배열에 대한 길이를 직접 구하면 행의 크기를 알 수 있다.
열의 크기
2차 배열의 모든 행에 대한 열 크기가 항상 동일하다는 보장이 없기 때문에 열의 크기는 각 행마다 개별적으로 구해야 한다.
4) 가변배열
2차 배열의 정확한 개념은 1차 배열의 각 원소가 다른 배열로 구성된 형태이다.
원소로서 포함되는 각 배열의 크기가 동일하지 않은 경우를 가변 배열이라고 한다.
항상 배열의 모든 행이 동일한 열로 구성되는 것은 아니다. (모든 줄의 칸 수가 같다는 보장은 없다는 의미)
가변배열이 자주 등장하는 것은 아니다. 95% 이상의 경우가 모든 행마다 열 크기가 동일한 경우이다.
5) 2차 배열과 반복문
배열의 모든 원소 스캔하기
2차 배열의 모든 원소를 반복문으로 스캔하기 위해서는 중첩 반복문을 사용해야 한다.
이 때 부모 반복문은 행에 대해 관여하고, 자식 반복문은 열에 대해 관여한다.
연습문제
문제 1
다음의 소스코드는 boolean 데이터를 저장하고 있는 배열에 대한 어떤 처리를 보여준다.
실행 결과에서 제시하는 것과 같이 배열에 저장되어 있는 값들을 반전(true
는 false
로, false
는 true
로) 변환하는 처리를 완성하시오.
const check_list = [true, false, false, true, false];
console.log("before --> " + check_list);
// ... 구현하세요.
console.log("after --> " + check_list);
출력결과
before --> true,false,false,true,false
after --> false,true,true,false,true
문제 2
다음 표는 어떤 학생의 과목별 점수이다.
HTML | CSS | Javascript |
---|---|---|
75 | 82 | 91 |
이 점수표를 grade
라는 이름의 1차원 배열로 구성하고 이 배열을 활용하여 총점을 의미하는 변수 sum
과 평균을 의미하는 변수 avg
를 구하시오.
문제 3
다음 표는 어떤 학생이 일요일부터 토요일까지 일주일간 아르바이트를 한 시간을 기록한 것이다.
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
7 | 5 | 5 | 5 | 5 | 10 | 7 |
이 학생의 시급은 원래 4,500원이었지만 목요일부터 5,200원으로 올랐다고 할 때 일주일간의 총 급여를 구하시오.
문제 4
아래의 화면은 어떤 사람이 쇼핑몰의 장바구니에 담은 상품에 대한 내역이다.
상품의 가격을 원소로 갖는 1차 배열 price
와 각 상품의 수량을 원소로 갖는 1차 배열 qty
를 정의하고 이 사람이 총 얼마를 결제해야 하는지 총 결제금액을 구하는 프로그램을
작성하시오.
총 결제금액의 변수 이름은 money
로 합니다.
문제 5
위 문제 4번에서 상품금액(판매가 x 수량)이 가장 비싼 항목은 얼마인지 구하시오.
문제 6
문제4번의 장바구니 내역에서는 모든 장바구니 상품이 개별 배송이라고 한다.
상품금액(판매가*수량)이 8만원 이상인 경우 무료로 배송이 된다고 할 때 무료로 배송되는 항목은 모두 몇 개 인지 구하는 프로그램을 구현하시오.
문제 7
다음은 어느 쇼핑몰의 상품 목록 화면이다.
위 화면에서 상품의 가격을 원소로 하는 배열 money
를 정의하고, “낮은가격순” 버튼이 눌러졌을 때 상품의 가격을 정렬하여 출력하는 코드를 작성하시오.
출력문은 아래와 같이 사용하세요.
console.log(money);
문제 8
아래의 배열 원소를 역순으로 배치하여 출력하시오.
const arr = [5, 3, 2, 8, 9];
문제 9
다음 표는 어느 학급의 성적표이다.
학생 | HTML | CSS | Javascript |
---|---|---|---|
둘리 | 78 | 89 | 96 |
도우너 | 62 | 77 | 67 |
또치 | 54 | 90 | 80 |
희동 | 100 | 99 | 98 |
위 표를 참고하여 학생 이름을 원소로 갖는 1차 배열 student
와 점수를 원소로 갖는 2차 배열 grade
를 정의하시오.
grade
는 학생 한명의 점수를 갖는 배열을 원소로 갖는 2차 배열 입니다.
이 배열을 활용하여 아래와 같이 출력하는 프로그램을 구현하시오.
둘리 총점: 263점, 평균: 87.67점
도우너 총점: 206점, 평균: 68.67점
또치 총점: 224점, 평균: 74.67점
희동 총점: 297점, 평균 99점
평균점수의 소수점 출력은 임의의 출력이며 프로그램이 계산하는 자리수를 그대로 출력하면 됩니다.
문제 10
위의 문제에서 반 평균을 출력하시오. 반 평균은 학생의 평균점수 총 합/학생수
로 구합니다.
문제 11
아래는 어느 게임 유저의 아이템 인벤토리이다.
판매를 위해 선택한 아이템의 상단에는 1개당 가격이 표시되고, 아이템을 판매할 때는 원래 가격의 90%
만 받을 수 있다고 한다.
첫 줄에 있는 아이템을 판매한다고 할 때 이 유저가 벌어들이는 골드(G)의 총액은 얼마인지 알아보려고 한다.
가격과 아이템 수량의 정보를 2차 배열로 구성하는 소스코드를 완성하고 아이템의 총 판매가격을 구하시오.
“단가-수량”을 한 세트로 하는 1차배열이 모인 2차 배열을 구성해야 합니다.
문제 12
어느 학급의 수학 시험 점수가 다음 표와 같았다.
이름 | 점수 |
---|---|
재석 | 82 |
민영 | 91 |
종민 | 54 |
광수 | 62 |
승기 | 88 |
새정 | 90 |
6명의 성적에 대해서 이름을 저장하고 있는 문자열 1차 배열 names와 점수를 저장하고 있는 1차 배열 points를 각각 정의하고 점수가 높은 순으로 이름을 출력하시오.
단, for문과 if문만 활용하여 구현해야 하며 출력 형태는 자유롭게 표현할 수 있습니다.
문제 13
수학에서 단위행렬은 주대각선의 원소가 모두 1이며 나머지 원소는 모두 0인 정사각 행렬이다.
즉, 아래와 같은 형태를 말한다.
\[\left[ \begin{matrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{matrix} \right]\]$5x5$ 크기의 빈 배열을 정의하고 이 배열을 단위행렬 형태로 원소를 채워 넣는 프로그램을 반복문과 조건문을 조합하여 작성하시오.
문제 14
철수와 민영은 도둑잡기 게임을 하고 있다.
도둑잡기 게임은 상대방의 카드 중 하나를 가지고 와서 내 카드와 일치하는 카드일 경우 가져온 카드와 내 카드의 쌍을 바닥에 내려 놓는 게임이다. 이렇게 해서 돌아가면서 카드를 한장씩 뽑게 되는데 카드를 모두 바닥에 내려 놓으면 이기는 게임이다.
철수는 [1, 5, 7, J, Q, A]
의 카드를 가지고 있다.
영희는 [2, 3, 4, 5, Q, K, A]
의 카드를 가지고 있다.
지금은 영희의 차례이다.
영희는 철수의 카드 중에서 몇 개를 가져올 수 있으며, 가져올 수 있는 카드는 몇 번째 카드인지 철수의 카드를 기준으로 출력하시오.
카드는 0번째 부터 카운트 한다.
출력 예시
가져올 수 있는 카드의 수: 3장
1번째 >> 5
4번째 >> Q
5번째 >> A