호쌤
호쌤 Just For Fun

[JS] 배열

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[JS] 배열≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[JS] 배열

학급의 성적표를 보고 각 학생별로 총점과 평균을 구해야 한다고 생각해 봅시다.

성적표가 아래와 같다면 3명씩 3과목이므로 총 9개의 변수가 필요할 것 입니다.

  국어 영어 수학
철수 92 81 76
영희 72 95 84
민혁 80 86 98
1
2
3
4
5
6
var kor1 = 92;
var kor2 = 71;
var kor3 = 80;
// ... 생략 ...
var math2 = 84;
var math3 = 98;

만약 30명의 학생에 대한 20과목에 대한 점수라고 가정한다면 프로그램은 좀 더 복잡해 지고 더 많은 변수를 소스코드상에 선언,할당 해야 할 것 입니다.

#01. 1차 배열

하나의 변수에 여러 개의 데이터를 그룹화 한 형태

1) 배열 만들기 (1)

배열의 선언

Javascript는 변수의 특성이 값이 할당 될 때 결정되기 때문에 선언은 일반 변수와 동일하다.

즉, 할당하기 전까지는 숫자, 문자열, 배열 등의 구분이 없다.

1
var myArr;

배열의 할당

대괄호([])안에 포함할 값들을 데이터 타입의 구분 없이 콤마(,)로 구분하여 나열한다.

1
2
myArr = [1, 2, 3.14, true, false, "hello", "world"];
console.log(myArr);
▶ 출력결과
1
[ 1, 2, 3.14, true, false, 'hello', 'world' ]

선언과 할당의 통합

1
2
var myArr = [1, 2, 3, 5, 7];
console.log(myArr);
▶ 출력결과
1
[ 1, 2, 3, 5, 7 ]

2) 배열 만들기 (2)

Array 클래스를 사용한 할당

new Array(...) 형식으로 생성한다.

여기서 말하는 new 키워드를 사용하여 생성할 때 Array는 클래스에 해당합니다.
Javascript에서의 클래스 개념은 뒤에서 별도의 단원을 통해 다루도록 합니다.

1
2
var newArr1 = new Array("hello", "world", 1, 2, 3, true, false);
console.log(newArr1);
▶ 출력결과
1
[ 'hello', 'world', 1, 2, 3, true, false ]

Array 클래스 사용시 주의할 점

new Array()로 배열을 생성할 때 ()안에 숫자 값 하나만 명시되는 경우, 숫자 값 만큼의 빈 칸을 갖는 배열이 생성된다.

배열의 각 칸은 모두 정의되지 않은 값(undefined)로 할당된다.

1
2
3
4
5
6
7
// 5라는 값을 원소로 갖는 한 칸으로 구성된 배열 만들기
var newArr2 = [5];
console.log(newArr2);

// 값이 존재하지 않는 5개의 빈 칸을 갖는 배열 만들기
var newArr3 = new Array(5);
console.log(newArr3);
▶ 출력결과
1
2
[ 5 ]
[ <5 empty items> ]

3) 배열의 원소에 접근하기

인덱스 번호를 통한 원소값 접근

배열의 각 원소는 0부터 시작하는 일련번호를 부여 받는데, 이를 배열의 인덱스 라고 한다.

1
2
3
4
5
var 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]);
▶ 출력결과
1
2
3
4
1
3.14
false
world

존재하지 않는 인덱스를 통한 접근

100번째 원소의 값을 출력하고자 할 경우 100번째 원소는 정의되어 있지 않으므로 undefined가 된다.

1
2
3
4
5
6
7
8
var item = myArr[100];
console.log(item);

if (item !== undefined) {
    console.log("100번째 원소 존재함");
} else {
    console.log("100번째 원소 존재하지 않음");
}
▶ 출력결과
1
2
undefined
100번째 원소 존재하지 않음

4) 배열의 크기

배열이름.length는 배열의 칸 수를 반환한다.

배열의 인덱스는 항상 0부터 크기-1까지 1씩 증가하면서 존재한다.

1
2
var myArr = [1, 2, 3.14];
console.log(myArr.length);
1
3

5) 반복문을 통한 활용

배열의 원소값을 일괄 할당하기

인덱스가 0부터 크기-1까지 1씩 증가한다는 특성을 활용하여 for문과 함께 사용하면 배열의 모든 원소에 대한 일괄 처리가 가능하다.

1
2
3
4
5
6
7
8
9
10
// 5칸으로 구성된 빈 배열 생성
var myArr = new Array(5);

// 0부터 배열의 길이(5)보다 작은 동안 반복
for (var i = 0; i<myArr.length; i++) {
    // i번째에 i*10을 저장
    myArr[i] = i * 10;
}

console.log(myArr);
▶ 출력결과
1
[ 0, 10, 20, 30, 40 ]

배열의 원소에 대한 총 합 구하기

1
2
3
4
5
6
7
8
9
10
11
12
var data = [ 10, 20, 30, 40, 50 ];

// 총 합을 구할 때는 항상 누적 합산을 수행할 변수를 0으로 초기화 해 놓고 반복을 수행해야 한다.
var sum = 0;

// 배열의 모든 원소에 대한 반복문 구성
for (var i = 0; i < data.length; i++) {
    // i번째 원소를 sum에 누적 합산
    sum += data[i];
}

console.log(sum);
▶ 출력결과
1
150

배열의 원소 중에서 가장 큰 값 구하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 원소값을 무작위로 갖는 배열
var data = [ 5, 2, 7, 9, 2 ];

// 비교를 위한 값 준비
var max = 0;

// 배열의 원소 수 만큼 반복
for (var i = 0; i < data.length; i++) {
    console.log("max=" + max + ", data[" + i + "]=" + data[i]);

    // max가 data의 i번째보다 작다면 i번째 원소를 max에 복사
    if (max < data[i]) {
        console.log(">> max에 " + data[i] + "를 복사");
        max = data[i];
    }
}

console.log("---------");
console.log("최대값 = " + max);
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
max=0, data[0]=5
>> max에 5를 복사
max=5, data[1]=2
max=5, data[2]=7
>> max에 7를 복사
max=7, data[3]=9
>> max에 9를 복사
max=9, data[4]=2
---------
최대값 = 9

배열의 순서를 뒤집기

반복 회수를 구하기 위한 연산
  1. 원소가 5개일 경우 반복 회수 : 2회

    5/2를 연산한다. 나머지는 버리게 되므로 2가 된다.

  2. 원소가 6개일 경우 반복 회수 : 3회

    6/2를 연산한다. 즉 배열의 길이/2를 구한다.

i번째 원소와 맞교환 하기 위한 반대쪽 원소의 인덱스

배열의길이 - i - 1;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var data = [ 1, 5, 2, 4, 3 ];
console.log(data);

for (var i=0; i<data.length/2; i++) {
    // 반대쪽 원소의 인덱스 구하기
    var k = data.length - i - 1;

    // i번째 원소와 k번째 원소 교환
    var tmp = data[i];
    data[i] = data[k];
    data[k] = tmp;
}

console.log(data);
▶ 출력결과
1
2
[ 1, 5, 2, 4, 3 ]
[ 3, 4, 2, 5, 1 ]

#02. 2차 배열

의 개념만 존재하는 1차 배열에 의 개념을 추가한 형태가 2차 배열 이다.

좀 더 정확한 개념은 1차 배열의 각 원소가 다른 배열로 구성된 형태라고 보는 것이 맞다.

1) 2차 배열 생성하기

배열의 원소로 다른 배열 포함하기

1
2
3
4
var a = [1, 2, 3];
var b = [4, 5, 6];
var myArr = [a, b];
console.log(myArr);
▶ 출력결과
1
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]

축약 표현

[]를 사용하여 1차원을 표현하고 그 안에 다시 []를 콤마로 구분하여 2차원을 구성한다.

1
2
3
// 2행 3열 배열 만들기
var myArr = [ [1, 2, 3], [4, 5, 6] ];
console.log(myArr);
▶ 출력결과
1
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]

2) 2차 배열의 원소에 접근하기

2행 3열인 경우 행의 인덱스는 0부터 1까지, 열의 인덱스는 0부터 2까지 존재한다.

배열에 저장된 원소에 접근하기 위해서는 변수이름 뒤에 행,열의 순서로 인덱스를 명시한다.

배열 원소 변경하기

  0번째 열 1번째 열 2번째 열
0번째 행 (0,0) = 10 (0,1) = 20 (0,2) = 30
1번째 행 (1,0) = 40 (1,1) = 50 (1,2) = 60
1
2
3
4
5
6
7
8
9
myArr[0][0] = 10;    // 0행0열
myArr[0][1] = 20;    // 0행1열
myArr[0][2] = 30;    // 0행2열

myArr[1][0] = 40;    // 1행0열
myArr[1][1] = 50;    // 1행1열
myArr[1][2] = 60;    // 1행2열

console.log(myArr);
▶ 출력결과
1
[ [ 10, 20, 30 ], [ 40, 50, 60 ] ]

배열 원소 개별 출력

1
2
3
4
5
6
7
console.log(myArr[0][0]);
console.log(myArr[0][1]);
console.log(myArr[0][2]);

console.log(myArr[1][0]);
console.log(myArr[1][1]);
console.log(myArr[1][2]);
▶ 출력결과
1
2
3
4
5
6
10
20
30
40
50
60

3) Array 클래스를 사용한 2차 배열 생성

배열의 원소로 다른 배열 포함하기

1차 배열의 각 원소에 또 다른 배열이 포함되는 형식으로 구성한다.

1
2
3
4
var a = new Array(1, 2, 3);
var b = new Array(4, 5, 6)
var data = new Array( a, b );
console.log(data);
▶ 출력결과
1
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]

축약표현

1
2
var data = new Array( new Array(1, 2, 3), new Array(4, 5, 6) );
console.log(data);
▶ 출력결과
1
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]

4) 가변배열

2차 배열의 정확한 개념은 1차 배열의 각 원소가 다른 배열로 구성된 형태이다. 원소로서 포함되는 각 배열의 크기가 동일하지 않은 경우를 가변 배열이라고 한다.

항상 배열의 모든 행이 동일한 열로 구성되는 것은 아니다. (모든 줄의 칸 수가 같다는 보장은 없다는 의미)

가변배열이 자주 등장하는 것은 아니다. 95% 이상의 경우가 모든 행마다 열 크기가 동일한 경우이다.

1
2
3
4
var a = [1, 3, 5, 7, 9];
var b = [2, 4, 6];
var data = [a, b];
console.log(data);
▶ 출력결과
1
[ [ 1, 3, 5, 7, 9 ], [ 2, 4, 6 ] ]
1
2
3
var data = [ [1, 3, 5, 7, 9],
             [2, 4, 6] ];
console.log(data);
▶ 출력결과
1
[ [ 1, 3, 5, 7, 9 ], [ 2, 4, 6 ] ]
1
2
3
4
var data = new Array(
            new Array(1, 3, 5, 7, 9),
            new Array(2, 4, 6) );
console.log(data);
▶ 출력결과
1
[ [ 1, 3, 5, 7, 9 ], [ 2, 4, 6 ] ]

5) 2차 배열의 행, 열 크기 구하기

행의 크기

2차 배열에 대한 길이를 직접 구하면 행의 크기를 알 수 있다.

1
2
var rowSize = data.length;
console.log(rowSize);
▶ 출력결과
1
2

열의 크기

2차 배열의 모든 행에 대한 열 크기가 항상 동일하다는 보장이 없기 때문에 열의 크기는 각 행마다 개별적으로 구해야 한다.

1
2
3
4
var colSize0 = data[0].length; // 0번째 행의 열 크기
var colSize1 = data[1].length; // 1번째 행의 열 크기
console.log(colSize0);
console.log(colSize1);
▶ 출력결과
1
2
5
3

6) 2차 배열과 반복문

배열의 모든 원소 스캔하기

2차 배열의 모든 원소를 반복문으로 스캔하기 위해서는 중첩 반복문을 사용해야 한다.

이 때 부모 반복문은 에 대해 관여하고, 자식 반복문은 에 대해 관여한다.

1
2
3
4
5
6
7
8
9
10
11
var twoArray = [ [1, 2], [10, 20, 30, 40] ];

// 배열의 `행`에 대한 반복
for (var i=0; i<twoArray.length; i++) {
    console.log(i + "번째 행 ----------");

    // i번째 행의 `열`에 대한 반복
    for (var j=0; j<twoArray[i].length; j++) {
        console.log(" :::: " + j + "번째 열 >> " + twoArray[i][j]);
    }
}
▶ 출력결과
1
2
3
4
5
6
7
8
0번째 행 ----------
 :::: 0번째 열 >> 1
 :::: 1번째 열 >> 2
1번째 행 ----------
 :::: 0번째 열 >> 10
 :::: 1번째 열 >> 20
 :::: 2번째 열 >> 30
 :::: 3번째 열 >> 40

7) 예제

성적 구하기

아래의 성적표를 보고 학생 이름을 1차 배열로, 학생들의 점수를 2차 배열로 표현한 뒤 각 학생별로 총점과 평균을 구해 출력하시오.

  국어 영어 수학
철수 92 81 76
영희 72 95 84
민혁 80 86 98
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 학생 성적 배열
var grade = [
    [ "철수", 92, 81, 76],
    [ "영희", 72, 95, 84],
    [ "민혁", 80, 86, 98]
];

for (var i=0; i<grade.length; i++) {
    // 행 단위의 합계 이므로 행 단위마다 합계를 위한 값이 새롭게 초기화 되어야 한다.
    var sum = 0;

    // i번째 행에서 0번째 열은 학생 이름이므로 합산에서 제외한다.
    for (var j=1; j<grade[i].length; j++) {
        sum += grade[i][j];
    }

    // 총점을 과목 수로 나누면 평균을 얻을 수 있다.
    // 여기서 과목수는 i번째 행의 길이에서 이름을 의미하는 한 칸을 제외해야 한다.
    var avg = sum / (grade[i].length-1);

    console.log("[" + grade[i][0] + "] 총점: " + sum + ", 평균: " + avg);
}
▶ 출력결과
1
2
3
[철수] 총점: 249, 평균: 83
[영희] 총점: 251, 평균: 83.66666666666667
[민혁] 총점: 264, 평균: 88

순차적으로 증가하는 값 할당하기

5행 7열로 구성된 2차 배열을 준비하고 배열의 모든 칸에 1부터 순차적으로 증가하는 값을 대입하세요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 5행 7열 배열 만들기
var cal = new Array(5);

for (var i=0; i<cal.length; i++) {
    cal[i] = new Array(7);
}

var count = 1;

for (var i=0; i<cal.length; i++) {
    var str = "";
    for (var j=0; j<cal[i].length; j++) {
        cal[i][j] = count++;
    }
}

console.log(cal);
▶ 출력결과
1
2
3
4
5
6
7
[
  [1, 2, 3, 4, 5, 6, 7],
  [8,  9, 10, 11, 12, 13, 14],
  [15, 16, 17, 18, 19, 20, 21],
  [22, 23, 24, 25, 26, 27, 28],
  [29, 30, 31, 32, 33, 34, 35]
]

#03. 배열을 통한 순환과 탐색

일반적인 경우 for문을 활용하여 배열을 탐색하지만 Javascript는 배열의 탐색을 위한 메서드를 제공한다.

1) 배열의 모든 원소 탐색하기

for문을 활용한 일반적인 배열의 탐색

아래 코드 패턴은 가장 기본적인 배열의 탐색을 보여준다.

for문은 반복을 중단하고자 할 경우 break를 사용한다.

1
2
3
4
5
6
7
8
9
const data1 = [10, 20, 30, 40, 50];

for (let i=0; i<data1.length; i++) {
    if (i == 3) {
        console.log(" ~~~ 반복중단!!!");
        break;
    }
    console.log("%d번째 원소 ==> %d", i, data1[i]);
}
▶ 출력결과
1
2
3
4
0번째 원소 ==> 10
1번째 원소 ==> 20
2번째 원소 ==> 30
~~~ 반복중단!!!

forEach 함수를 사용한 배열의 탐색

javascript는 배열객체에 포함되어 있는 몇가지 함수를 통해 배열의 원소를 탐색하는 기능을 제공한다.

그 중에서 forEach 함수는 배열의 모든 원소를 탐색하고 각각의 원소와 인덱스 번호를 파라미터로 하는 콜백함수 처리를 제공한다.

배열을 탐색하는 동안 각각의 원소에 대한 처리를 수행할 수 있도록 콜백함수를 지정한다.

forEach의 콜백함수에서 반복을 중단하고자 return을 사용할 경우 현재 동작중인 콜백만 종료될 뿐 전체 순환에는 영향이 없다.

1
2
3
4
5
6
7
8
9
const data2 = [10, 20, 30, 40, 50];

data2.forEach((v, i) => {
    if (i == 3) {
        console.log(" ~~~ 반복중단!!!");
        return true;
    }
    console.log("%d번째 원소 ==> %d", i, v);
});
▶ 출력결과
1
2
3
4
5
0번째 원소 ==> 10
1번째 원소 ==> 20
2번째 원소 ==> 30
~~~ 반복중단!!!
4번째 원소 ==> 50

2) 탐색 중단하기

some 함수는 콜백함수를 통한 배열의 탐색을 중단할 수 있는 기능을 제공한다.

콜백함수 안에서 true를 리턴하는 순간 탐색이 중단된다.

1
2
3
4
5
6
7
8
9
10
const data3 = [10, 20, 30, 40, 50];

data3.some((v, i) => {
    // some 함수는 콜백함수가 true를 리턴하는 순간 순환을 중단한다.
    if (i == 3) {
        console.log(" ~~~ 반복중단!!!");
        return true;
    }
    console.log("%d번째 원소 ==> %d", i, v);
});
▶ 출력결과
1
2
3
4
0번째 원소 ==> 10
1번째 원소 ==> 20
2번째 원소 ==> 30
~~~ 반복중단!!!

3) 배열의 각 원소에 대한 처리 결과를 새로운 배열에 담아내기

for문을 활용한 방법

반복이 수행되기 전에 빈 배열을 준비하고, 반복문 안에서 배열의 원소를 하나씩 추가하는 형태로 구현한다.

1
2
3
4
5
6
7
8
const data4 = [1, 2, 3, 4, 5];
const d1 = [];

for (let i=0; i<data4.length; i++) {
    d1.push(data4[i] + 1);
}

console.log(d1);
▶ 출력결과
1
[2, 3, 4, 5, 6]

forEach를 활용한 방법

for문과 마찬가지로 빈 배열을 미리 준비해야 한다.

1
2
3
4
5
6
7
8
const data5 = [1, 2, 3, 4, 5];
const d2 = [];

data5.forEach((v, i) => {
    d2.push(v + 1);
});

console.log(d2);
▶ 출력결과
1
[2, 3, 4, 5, 6]

map함수 사용하기

map 함수에서 리턴하는 값들은 하나의 배열에 대한 원소가 된다.

1
2
3
4
5
6
7
8
const data6 = [1, 2, 3, 4, 5];

// map함수에 전달된 콜백이 리턴하는 값들을 하나의 배열로 묶어서 hello에 저장
const hello = data6.map( function(v, i) {
    return v + 1;
});

console.log(hello);
▶ 출력결과
1
[2, 3, 4, 5, 6]

위의 코드를 화살표 함수 형식으로 표현하면 다음과 같이 축약할 수 있다.

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

const hello = data6.map( (v, i) => v + 1 );

console.log(hello);

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[JS] 배열≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus