Juni_Dev_log

(node.js) [Part.3] 노드와 자바스크립트 - 배열 이해하기 본문

Theorem (정리)/node.js

(node.js) [Part.3] 노드와 자바스크립트 - 배열 이해하기

Juni_K 2020. 11. 30. 13:35

배열 이해하기

배열에 대해서 간단하게 알아보자.

배열은 여러 개의 데이터를 하나의 변수에 담아 둘 수 있어서 자주 사용되며, 배열 안에 들어있는 요소들을 대괄호 [ ]를 이용해서 접근할 수 있다.

배열이 만들어지는 모양은 다음과 같다.

 

배열이 만들어지는 모양

만약 다섯 명의 사용자 정보를 관리하기 위해 다섯 개의 객체를 만들고 각각 다른 이름의 변수에 할당한다면 매번 다섯 개의 변수에 접근하고 관리해야한다.

그런데 Users 변수를 하나만 만들고 그 안에 다섯 개의 사용자 객체를 넣어 한꺼번에 관리할 수 있다면 각각을 따로 관리하는 것보다 훨씬 편리해진다.

 

이렇게 여러 개의 데이터를 편리하게 다룰 수 있기 때문에 배열을 자주 사용한다.

배열에 추가되는 요소들은 0부터 시작하는 인덱스(Index) 번호로 접근할 수 있다. 배열을 만들 때는 대괄호 [ ] 를 이용해서 만들고 그 안에 요소를 추가할 때는 push() 메소드를 사용한다.

 

ch03_test8.js 를 만들고 다음코드를 입력한다.

var Users = [{name:'소녀시대',age:20},{name:'레드벨벳',age:15}];

Users.push({name:'원더걸스',age:23});

console.log('사용자 수 : %d',Users.length);
console.log('첫 번째 사용자 이름 : %s',Users[0].name);

//사용자 수 : 3
//첫 번째 사용자 이름 : 소녀시대

배열 객체를 하나 만든 후, Users 변수에 할당했다.

배열 안에는 name과 age 속성을 가진 객체가 두 개 들어있고, 배열에 새로운 객체를 추가하기 위해서 push() 메소드를 활용해서 추가했다.

배열에 들어있는 요소들의 개수를 알아내려면 length 속성을 사용하면 된다.

각각의 배열 요소에 접근하기 위해서는 대괄호와 함께 그 요소의 인덱스 정보를 사용한다.

 

또한, 변수에는 함수를 할당할 수 있다. 따라서 배열의 각 요소에도 함수를 직접 할당할 수 있다.

push()함수를 호출하여 배열 객체에 추가해보도록 한다.

ch03_test9.js 를 만들고 다음과 같이 입력한다.

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:22}];

var add = function(a,b){
    return a+b;
};

Users.push(add);

console.log('배열 요소의 수 : %d',Users.length);
console.log('세 번째 요소로 추가된 함수 실행 : %d', Users[2](10,10));
//배열 요소의 수 : 3
//세 번째 요소로 추가된 함수 실행 : 20

add 변수에 할당되었던 더하기 함수를 Users 배열에 그대로 추가했다.

이렇게 추가한 배열 요소는 세 번째 요소가 되므로 Users[2] 코드로 접근할 수 잇다.

이렇게 접근한 요소가 함수이므로 함수를 실행하기 위해서는 Users[2](10,10) 코드를 사용할 수 있다.

코드 형태가 만들어져 약간 복잡하게 보이기는 하지만, 이런 코드가 어떻게 만들어질 수 있는지를 생각하면서 보면 이해가 될 것이다.

 

함수를 넣어두고 그 함수를 실행하는 방식은 자바나 C언어 같은 타입 기반 언어에서는 보기 힘들다.

그만큼 자바스크립트의 함수는 아주 유연하게 사용할 수 있다.

 

배열의 모든 요소 하나씩 확인하기

배열 안에 있는 모든 요소를 하나씩 확인하는 방법에 대해서 알아본다.

가장 간단한 방법은 for 문을 사용하는 것이다.

ch03_test10.js 를 만들어보자.

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:16},{name:'티아라',age:18}];

console.log('배열 요소의 수 : %d',Users.length);
for(var i=0; i<Users.length; i++){
    console.log('배열 요소 #'+ i +' : %s',Users[i].name);
}

//배열 요소의 수 : 3
//배열 요소 #0 : 소녀시대
//배열 요소 #1 : 걸스데이
//배열 요소 #2 : 티아라

Users 배열 안에 들어있는 각 객체들을 for 문 안에서 하나씩 접근할 수 있다.

for문처럼 배열의 각 요소에 하나씩 접근할 수 있는 또 다른 방법으로는 forEach() 메소드를 사용하면 된다.

forEach() 메소드를 호출할 때는 함수를 파라미터로 전달하게 되는데 이 함수는 배열에 들어있는 각 요소를 확인할 때마다 반복해서 호출한다.

 

하나의 함수가 다른 함수의 파라미터로 전달될 수 있는가?

함수를 만들 때, 변수를 파라미터로 전달할 수 있다. 그런데, 자바스크립트에서는 함수가 변수에 할당될 수 있다고 했으므로, 하나의 함수가 다른 함수의 파라미터로 전달될 수 있다. 

ch03_test10.js 코드에 추가한다.

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:16},{name:'티아라',age:18}];

...

console.log('\nforEach 구문 사용하기');
Users.forEach(function(item, index){
    console.log('배열 요소 #' + index + ' : %s',item.name);
})

//forEach 구문 사용하기
//배열 요소 #0 : 소녀시대
//배열 요소 #1 : 걸스데이
//배열 요소 #2 : 티아라

두 개의 파라미터가 들어가는데, 첫 번째는 배열의 각 요소이며 두 번째는 각 요소의 인덱스 값이다.

만약, forEach()문이 실행될 때 오류가 발생했다면, 대소문자를 구분하기 때문에 소문자로 입력하면 오류가 발생한다.

또한, 소괄호 안에 입력하는 파라미터의 경우에도 forEach(item,index)가 아니라 forEach(index,item)으로 순서를 바꾸면 아이템과 인덱스 값이 바뀌어 들어가게 된다. 다시 말해 순서를 잘 지켜야 오류가 없이 실행된다.

배열에 값 추가 및 삭제하기

배열의 모든 요소를 확인하는 방법에 대해서 알아보았다.

마지막으로 배열에 값을 추가하거나 삭제하는 방법에 대해서 알아보자.

속성 / 메소드 이름 설명
push(object) 배열의 끝에 요소를 추가한다.
pop() 배열의 끝에 있는 요소를 삭제한다.
unshift() 배열의 앞에 요소를 추가한다.
shift() 배열의 앞에 있는 요소를 삭제한다.
splice(index, removeCount, [Object]) 여러 개의 객체를 요소로 추가하거나 삭제한다.
slice(index, copyCount) 여러 개의 요소를 잘라내어 새로운 배열 객체로 만든다.

 

먼저 배열의 끝에 요소를 추가하거나 삭제할 때, push() 와  pop() 메소드를 사용한다.

배열에 객체를 추가하는 경우가 많기 때문에, push() 메소드는 자주 사용한다.

push() 와 pop() 메소드로 배열의 끝에 요소를 추가하거나 삭제하기

 

사용자 객체를 배열에 넣었다가 삭제하는 기능을 만들기 위해서 ch03_test11.js 파일을 만들고 다음과 같이 입력한다.

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:17},{name:'티아라',age:18}];
console.log('push() 호출 전 배열 요소의 수 : %d',Users.length);

Users.push({name:'원더걸스',age:24});
console.log('push() 호출 후 배열 요소의 수 : %d',Users.length);

Users.pop();
console.log('pop() 호출 후 배열 요소의 수 : %d',Users.length);

//push() 호출 전 배열 요소의 수 : 3
//push() 호출 후 배열 요소의 수 : 4
//pop() 호출 후 배열 요소의 수 : 3

push() 와 pop() 메소드는 배열의 가장 끝 부분에 요소를 추가하거나 삭제하지만, unshift()와 shift() 메소드는 가장 앞에 요소를 추가하거나 삭제한다.

 

unshift()로 배열의 앞부분에 요소를 추가하고 shift()메소드로 배열의 앞부분에 있는 요소를 삭제하기

ch03_test12.js 를 만들고 다음과 같이 입력한다.

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:17},{name:'티아라',age:18}];
console.log('unshift() 호출 전 배열 요소의 수 : %d',Users.length);

Users.unshift({name:'원더걸스',age:24});
console.log('unshift() 호출 후 배열 요소의 수 : %d',Users.length);

Users.shift();
console.log('shift() 호출 후 배열 요소의 수 : %d',Users.length);

//unshift() 호출 전 배열 요소의 수 : 3
//unshift() 호출 후 배열 요소의 수 : 4
//shift() 호출 후 배열 요소의 수 : 3

그런데, 배열 중간에 있는 요소를 삭제하고 싶다면 어떻게 해야할까?

delete 키워드를 사용하면 인덱스를 이용해 배열 요소를 삭제할 수 있다. ch03_test13.js 를 만들고 코드를 입력한다.

 

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:17},{name:'티아라',age:18}];
console.log('delete 키워드로 요소 삭제 전 배열 요소의 수 : %d',Users.length);

delete Users[1];
console.log('delete 키워드로 요소 삭제 후');
console.dir(Users);

/*
delete 키워드로 요소 삭제 전 배열 요소의 수 : 3
delete 키워드로 요소 삭제 후
[ { name: '소녀시대', age: 20 }, <1 empty item>, { name: '티아라', age: 18 } ]
*/

배열 객체에는 세 개의 객체가 들어있는데, delete 키워드를 사용해 두 번째 요소를 삭제한다.

그런데, 이상한 점을 알 수 있는데, 두 번째 요소가 삭제되었는데 배열의 개수는 똑같이 3개이다. 

이것은 배열 안에 요소를 담아둘 수 있는 공간이 그대로 남겨진채 객체만 삭제되었기 때문이다.

이런 경우에 빈 공간이 undefined로 남아 배열 객체를 다룰 때 혼동을 일으킬 수 있다.

 

따라서, 배열 요소를 담는 공간까지 삭제하는 splice() 메소드를 사용하는 것이 좋다.

splice() 메소드는 배열 요소 여러 개를 한꺼번에 추가하거나 삭제할 수 있는 방법이다.

 

splice() 메소드로 배열 요소 여러개를 한꺼번에 추가하거나 삭제하기

splice() 메소드를 호출할 때, 전달하는 첫 번째 파라미터는 인덱스 값으로 배열의 몇 번째 요소부터 처리할 것인지를 지정한다.

두 번째 파라미터는 삭제할 요소의 개수를 지정한다. 만약, 다섯 개의 객체가 들어있는 Users 배열에 세 번째와 네 번째 요소를 삭제하고 싶다면, 다음과 같이 호출한다.

Users.splice(2,2);

splice() 메소드를 이용해 배열 요소를 추가하거나 삭제하기

세 번째 인덱스 값이 2이므로 첫 번째 파라미터의 값은 2가 되고, 두 개의 요소를 삭제할 것이므로 두 번째 파라미터의 값도 2가 된다.

만약, 값을 추가하고 싶다면 두 번째 파라미터의 값을 0으로 입력한 후 추가하려는 객체를 파라미터로 전달한다.

ch03_test13.js 를 다시 만들고 다음 코드를 추가한다.

 

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:17},{name:'티아라',age:18}];
console.log('delete 키워드로 요소 삭제 전 배열 요소의 수 : %d',Users.length);

...

Users.splice(1,0,{name:'애프터스쿨',age:21});
console.log('splice()로 요소를 인덱스 1에 추가한 후');
console.dir(Users);

Users.splice(2,1);
console.log('splice()로 인덱스 2의 요소를 1개 삭제한 후');
console.dir(Users);

/*
splice()로 요소를 인덱스 1에 추가한 후
[
  { name: '소녀시대', age: 20 },
  { name: '애프터스쿨', age: 21 },
  <1 empty item>,
  { name: '티아라', age: 18 }
]
splice()로 인덱스 2의 요소를 1개 삭제한 후
[
  { name: '소녀시대', age: 20 },
  { name: '애프터스쿨', age: 21 },
  { name: '티아라', age: 18 }
]
*/

slice() 메소드로 배열 일부 요소 복사하여 새로운 배열 만들기

마지막으로 slice() 메소드에 대해서 알아보자.

slice() 메소드는 배열의 일부 요소들을 복사하여 새로운 배열을 만들어준다.

slice() 메소드를 이용해 배열의 일부 요소를 복사하여 새로운 배열 만들기

slice() 메소드에 전달하는 파라미터는 두 개이다. 첫 번째는 복사할 요소의 시작 위치이며 두 번째는 끝 위치이다.

ch03_test14.js 파일을 만들고 코드를 작성한다.

var Users = [{name:'소녀시대',age:20},{name:'걸스데이',age:17},{name:'티아라',age:18},{name:'애프터스쿨',age:25}];

console.log('배열 요소의 수 : %d',Users.length);
console.log('원본 Users');
console.dir(Users);

var Users2 = Users.slice(1,3);

console.log('slice()로 잘라낸 후 Users2');
console.dir(Users2);

var Users3 = Users.slice(1);
console.log('slice()로 잘라낸 후 Users3');
console.dir(Users3);

/*
배열 요소의 수 : 4
원본 Users
[
  { name: '소녀시대', age: 20 },
  { name: '걸스데이', age: 17 },
  { name: '티아라', age: 18 },
  { name: '애프터스쿨', age: 25 }
]
slice()로 잘라낸 후 Users2
[ { name: '걸스데이', age: 17 }, { name: '티아라', age: 18 } ]
slice()로 잘라낸 후 Users3
[
  { name: '걸스데이', age: 17 },
  { name: '티아라', age: 18 },
  { name: '애프터스쿨', age: 25 }
]
*/

데이터를 배열 객체에 넣어두고 사용할때가 많으므로 배열 객체의 사용법은 잘 알아두자.

또한 이와 같은 코드는 노드를 사용할 때, 자주 볼 수 있으므로 알고 있던 내용이 아니라면 익숙해질 수 있도록 반복해서 연습해야한다.

Comments