[TIL][JavaScript] 배열

Heejun Kwon·2021년 6월 14일
0

TIL

목록 보기
1/5
post-thumbnail

본 TIL( Today I Learned )은 그날그날의 공부한 내용들을
나중에 보더라도 쉽게 찾을 수 있도록 정리하고 있습니다.

잘못된 부분과 새로 배우는 내용이 있을 경우나
더욱 가독성이 좋아지도록 지속적으로 수정될 예정입니다.
(메서드 추가 및 메서드 순서 정리예정)

1차 작성일자 : 2021.06.14
2차 수정일자 : 2021.06.15
(map(), filter(), reduce(), every(), some(), indexOf(), lastIndexOf() 추가)

1. 배열의 선언 및 생성


자바스크립트의 배열 선언 및 생성 방법은 크게 두 가지로 나눠어진다.

1. 배열 리터럴을 이용한 선언 및 생성

let arr = [ ];
let arr = [ "요소1", "요소2", "요소3" ];

2. 배열 생성자를 이용한 선언 및 생성

let arr = new Array( );
let arr = new Array( "요소1", "요소2", "요소3" );

❗ 선호되는 방식 : 1번

1번의 배열 리터럴을 이용한 선언 및 생성 방식이 적극 권장되고 있다.
이유는

  • 짧고 간결한, 직관적인 배열의 생성이 가능하다.
  • new Array( ) 보다 속도가 전반적으로 빠르다.
  • new Array( ) 는 number 하나만 올 경우 이를 배열 길이로 인식한다.
    let arr = [ 5 ]; 은 number타입 정수 5가 들어간 배열이 생성되고
    let arr = new Array( 5 )은 길이 5의 empty로 채워진 배열이 생성된다.
    let arr = [ 5.1 ]의 경우 number타입 5.1이 들어간 배열이 생성되지만
    let arr = new Array( 5.1 )의 경우
    3.14의 길이를 가진 배열을 생성하려다 에러가 발생하는 등 문제가 많다.

자바스크립트 배열에의 특징에 대해 간략하게 설명하고 넘어가면

규칙이 엄한 다른 언어들과 다르게 배열 생성 시
배열의 길이를 지정해주지 않아도 된다는 특징으로 인해
배열의 길이가 동적이기 때문에 요소의 추가, 삭제 등에서 사용하기가 편하다.

또한 배열 안에 같은 타입만 들어갈 수 있는 것이 아니라
number타입, string타입, 객체, 함수 등 한 배열 내에
여러 타입의 값들이 들어갈 수 있다.


2. 배열의 요소 추가

배열의 요소를 추가하는 방법은 크게 세가지로 나뉘어진다.

1. 배열 선언 및 생성 시 함께 추가하기

let arr = [ "요소1", "요소2", "요소3" ];
let arr = new Array( "요소1", "요소2", "요소3" );

배열 선언, 생성과 동시에 위와 같이 요소들을 추가해줄 수 있다.

2. 이미 선언된 배열에 인덱스(index)로 요소 추가하기

let arr = [];
arr[0] = "요소1";
arr[1] = "요소2";
arr[2] = "요소3";

배열의 공간은 각각의 인덱스가 지정되어 있고
인덱스는 0부터 1씩 커져나간다.
위의 방식은
0번 인덱스를 가진 공간에 문자열 "요소1"을 추가
1번 인덱스를 가진 공간에 문자열 "요소2"을 추가
2번 인덱스를 가진 공간에 문자열 "요소3"을 추가한다.

3. push() 메서드를 이용한 추가

let arr = [];
arr.push("요소1");
arr.push("요소2");
arr.push("요소3");

또는

arr.push("요소1", "요소2", "요소3");

push( ) 메서드는 배열의 끝에 ( ) 내의 요소들을 추가해준다.
추가적으로 push( ) 메서드는 push()로 요소가 추가된 배열의
새로운 길이를 반환(return)한다.


3. 배열의 초기화

let arr = [ "요소1", "요소2", "요소3" ];

의 배열이 선언되어 있을 때 이 배열을 초기화(빈 배열로 만들기)
하고 싶다면, 크게 세 가지 방법이 존재한다.

1. 빈 배열 [ ] 로 재선언하기

arr = [];
  • 이 방법은 배열을 비우는 것이 아닌
    새로운 빈 배열을 만들어 arr에 참조시키는 방법이다.
  • 매우 간단한 방법이지만 문제가 있을 수 있다.
let arr2 = arr; 

을 통해 arr2가 arr과 같은 배열을 참조하도록 한 뒤

arr = [];

을 하여 arr을 빈 배열로 재선언한다면 arr2의 값은 어떻게 될까?
arr은 비어있는 새 배열을 참조하게 되었지만
arr2는 기존 arr이 가지고 있던 배열을 그대로 참조하고 있기 때문에
arr2에는 [ "요소1", "요소2", "요소3" ] 배열이 남아있다.
이런 식으로 하나의 배열을 여럿이 참조하고 있을때
이를 고려하여 사용해야 하는 방법이다.

2. 배열의 길이를 0으로 하기

arr.length = 0;

배열.length는 배열의 길이를 의미한다.

위처럼 배열의 길이를 0으로 할 경우 빈 배열 [ ]로 초기화할 수 있다.
1번 못지 않게 간단하면서 1번 방법과 다르게
여럿이서 참조하고 있더라도 참조중인 배열을 초기화 하는 것이기 때문에
같은 배열을 참조중인 변수에서 모두 [ ] 의 결과를 얻을 수 있다.

3. for 반복문과 pop 메서드를 이용하기

for( let i = 0; i < arr.length; i++ ) {
	arr.pop();
}

위의 코드는 arr 배열의 길이만큼 반복을 하며 pop( ) 메서드를 실행한다.
pop( ) 메서드는 배열의 마지막 값을 빼서 반환(return)하는 메서드로
배열의 길이만큼 반복하며 모든 요소를 빼서 빈공간으로 만드는 방법이다.

위와 같이 세 가지 방법이 존재하는데
1번 방법을 사용할 경우, 설명에서 언급한 사에 대해 주의하며 사용하자.


4. 배열에서 사용할 수 있는 메서드들

1) push()

let arr = [];
arr.push("요소");			//1을 반환
arr.push(3);				//2를 반환
arr.push(3.14);				//3을 반환
arr.push("요소1", "요소2", "요소3");	//6을 반환

위에서 요소를 추가하는 설명에서 보았던 push( ) 메서드이다.
자바에서는 arr[1]과 같이 인덱스를 통해서만
요소를 추가할 수 있어 불편했는데
자바스크립트에서는 push( ) 메서드를 통해서 배열의 끝에
배열의 길이와 상관없이 요소들을 추가해줄 수 있다.

위처럼 한개씩 추가할 수도 있고, 여러개를 한번해 추가해 줄 수 있다.

그리고 push()를 하고 난 뒤의 배열의 길이를 반환해준다.


2) pop()

let arr = ["Apple", "Banana", "Orange"];
arr.pop( ); //"Orange"를 반환

이 또한 위에서 잠깐 보고온 메서드로
배열의 마지막 값을 빼내고(제거하고) 해당 요소를 반환해준다.

배열의 마지막에 있는 요소를 가져오고 싶을때나
배열의 마지막 요소를 제거하고 싶을 때 사용할 수 있다.


3) sort() 와 reverse()

let arr = ["Orange", "Banana", "Apple"];
arr.sort( ); 		//결과 ["Apple", "Banana", "Orange"];
arr.reverse( );		//결과 ["Orange", "Banana", "Apple"];

sort( ) 메서드와 reverse( ) 메서드는 정렬에 사용되는 메서드이다.
sort( ) 메서드는 오름차순 정렬을( 1, 2, 3... )
reverse( ) 메서드는 내림차순 정렬을( 3, 2, 1...) 해준다.
문자열 요소들이 든 배열을 sort할 경우 첫 문자값을 기준으로
정렬을 해주고, 같은 문자라면 그 뒤의 문자들도 체크해 정렬한다.

let arr2 = [3, 31, 10, 1, 4];
arr2.sort( );		//결과 [1, 10, 3, 31, 4]

그렇다면 숫자가 든 배열도 sort( ) 메서드를 사용하면
당연히 1, 2, 3, 4... 처럼 오름차순이 되겠지? 라고 생각하며
위와 같이 숫자 배열에 sort( ) 정렬을 해 보면 이상한 결과가 나올 것이다.

왜냐하면 sort( )와 reverse( )는 문자를 기준으로 정렬하기 때문에
가장 첫번째 문자를 체크하고 이를 기준으로 정렬하여
위와 같이 1, 10, 3, 31, 4와 같은 결과가 나오는 것이다.

숫자 배열을 오름차순, 내림차순 정렬하고 싶다면

arr.sort( function(a, b) {return a-b;} );	//오름차순
arr.sort( function(a, b) {return b-a;} );	//내림차순

와 같이 sort 메서드를 사용해야 한다.
sort의 괄호 안에 함수가 들어와있는데,
자바를 배워본 적이 있다면 비교측정기 Comparator 를 떠올리면 된다.

정렬을 할 때, 문자가 아닌 숫자를 기준으로 정렬하겠다는 것이다.

배열의 요소 a와 배열의 요소 b를 서로 빼서, 그 값이 0보다 작을 경우
a, b 순으로 요소를 정렬한다는 것이 첫번째 줄의 sort 오름차순이고,
배열의 요소 b와 배열의 요소 a를 서로 빼서, 그 값이 0보다 작을 경우
b, a 순으로 요소를 정렬한다는 것이 두번째 줄의 sort 내림차순이다.


4) forEach()

let fruits = ["Orange", "Banana", "Apple"];
fruits.forEach( function(elt, i, array) {
	console.log(elt);
});
//실행결과
"Orange"
"Banana"
"Apple"

forEach 메서드는 반복문을 보다 사용하기 쉽게 만들어준다.

배열 내의 모든 요소에 순차적으로 접근하는데,
접근한 요소는 elt에
현재 인덱스는 i에
메서드를 호출한 배열 전체는 array에 저장되어 있어
모든 요소들을 순차적으로 출력하고 싶다면 console.log( elt )
모든 요소들을 순차적으로 출력하되 뒤에 인덱스를 붙이고 싶다면
console.log( elt + i ) 를 function 중괄호 내부에서 실행하면 된다.

array같은 경우 console.log(array)로 출력해보면
["Orange", "Banana", "Apple"] 배열이 그대로 출력되는 것을 볼 수 있다.

let fruits = ["Orange", "Banana", "Apple"];
fruits.forEach( function(elt) {
	console.log(elt);
});

만약, 요소만이 필요하다면 function의 인자에 elt만 입력해도 된다.
단, 요소와 배열만 필요한 경우엔 인자 세 개를 모두 선언해야 한다.


5) toString()

let fruits = ["Orange", "Banana", "Apple"];
console.log(fruits);		//결과  ["Orange", "Banana", "Apple"]
console.log(fruits.toString());	//결과  Orange,Banana,Apple

toString() 메서드는 배열을 string 문자열로 반환해준다.

배열을 바로 출력할 경우 괄호가 쳐진 상태로 사이에 공백이 존재하고
toString()을 이용해 출력할 경우 괄호 없이
사이가 ,로 연결된 배열 문자열을 확인할 수 있다.


6) join()

let fruits = ["Orange", "Banana", "Apple"];
console.log(fruits.join("와 "));    //결과 Orange와 Banana와 Apple

join 메서드는 배열의 사이를 특정 문자열로 연결시키고
이를 string 문자열로 반환하는 메서드이다.

과일들 사이에 "와 " 로 연결시키고 싶어 join의 괄호에 "와 "를 넣어
join을 호출하면 Orange와 Banana와 Apple 이라는
string 문자열을 반환받을 수 있다.


7) shift()

let fruits = ["Orange", "Banana", "Apple"];
fruits.shift();
console.log(fruits);	//결과 ["Banana", "Apple"]

shift() 메서드는 배열의 첫번째 요소를 빼내서 반환해준다.

pop()이 마지막 요소를 빼내서 반환해줬었는데
pop()이랑 반대되는 메서드라고 기억하면 된다.


8) unshift()

let fruits = ["Orange", "Banana", "Apple"];
fruits.unshift("Grape");
console.log(fruits);	//결과 ["Grape", "Orange", "Banana", "Apple"]

shift( ) 메서드가 첫번째 요소를 빼내서 반환해줬다면
unshift( ) 메서드는 배열의 첫번째에 요소를 추가해주는 것이다.

unshift( ) 메서드로 배열에 "Grape"를 추가하니 위처럼
배열의 첫번째에 "Grape" 요소가 생긴 것을 볼 수 있다.


9) splice()

let fruits = ["Orange", "Banana", "Apple"];
fruits.splice(0, 2, "Kiwi");
console.log(fruits);	//결과 ["Kiwi", "Apple"]

splice(pos, amount, newelt) 메서드는
특정 인덱스부터(pos) 몇개(amount)의 요소를 제거한 뒤
그 자리에 어떤 요소(newelt)를 추가할 수 있도록 해주는 메서드이다.

위에서는 index 0번부터 2개를 제거했으니
"Orange", "Banana"가 제거되고, 그 자리에 "Kiwi"가 추가되어
fruits 배열에는 "Kiwi"와 "Apple"만이 남는다.

fruits.splice(0, 2, "Kiwi", "Strawberry", "Grape");

처럼 newelt로 여러개의 요소를 줘도 되고

fruits.splice(0, 2);

처럼 newelt를 주지 않을 경우 제거만 하는 용도로 사용할 수 있다.


10) concat()

let fruits = ["Orange", "Banana"];
let fruits2 = ["Grape"];
let fruits3 = ["Apple"];
console.log(fruits.concat(fruits2));
//결과  ["Orange", "Banana", "Grape"]
console.log(fruits.concat(fruits2, fruits3));
//결과  ["Orange", "Banana", "Grape", "Apple"]

concate( ) 메서드는 배열을 합쳐서 새로운 배열을 반환하는 메서드이다.
두 개의 배열을 합치거나 한번에 그보다 많은 배열을 합칠 수 있다.

주의할 점은 호출한 배열에 합쳐주는 것이 아니라
호출한 배열과 인자로 온 배열들을 합친 새로운 배열을 반환
해준다는 것에 유의하자.
만약 합친 배열을 원래의 배열에 저장하고 싶다면

let fruits = ["Orange", "Banana"];
let fruits2 = ["Grape"];
let fruits3 = ["Apple"];
fruits = fruits.concat(fruits2, fruits3);

이와 같이 기존 배열에 재선언해주어야 한다.


11) slice()

let fruits = ["Orange", "Banana", "Grape", "Apple"];
console.log(fruits.slice(1, 2));	//결과 ["Banana"]
console.log(fruits.slice(1));		//결과 ["Banana", "Grape", "Apple"]

slice( ) 메서드는 원하는 인덱스부터 원하는 인덱스까지
배열을 잘라내서 새로운 배열로 반환해준다.

인덱스를 하나만 입력한다면 해당 인덱스부터 끝까지 잘라내서 가져온다.
잘라낸다고 해서 원래 배열이 변하지는 않는다.


12) map()

let num = [1, 2, 3, 4, 5];
let result = num.map( function(elt, i, array) {
	return elt * 3;
});
console.log(result);	//결과 [3, 6, 9, 12, 15]

map( ) 메서드는 배열의 모든 요소에 순차적으로 접근해서
elt에 배열의 요소
i에 배열 인덱스
array에 호출한 배열 전체를 담는다.

이를 활용하여 새로운 배열을 만들어 낼 수 있는데.
위의 예제는 각 요소에 3씩을 곱한 새로운 배열을 만들어낸다.

호출된 배열의 첫 번째 요소에 3을 곱한 값을
새 배열의 첫 번째 요소에 담고,
다음 두 번째 요소에 3을 곱한 값을 새 배열의 두 번째 요소에 담는다.
이를 호출한 배열의 요소 갯수만큼 반복하여
전체적으로 3이 곱해진 새 배열을 반환받는 것이다.

let num = [1, 2, 3, 4, 5];
let result = num.map( function(elt, i, array) {
	if(elt >= 3) return elt * 3;
});
console.log(result);	//결과  [undefined, undefined, 9, 12, 15]

만약 if문을 통해서 특정 인덱스의 요소에 접근했을 때
return을 하지 않는다면 새 배열의 해당 인덱스에는 undefined
즉, 빈 공간이 채워지게 된다.


13) filter()

let num = [1, 2, 3, 4, 5];
let result = num.filter( function(elt, i, array) {
	return elt >= 3;
});
console.log(result);	//결과  [3, 4, 5]

filter( ) 메서드는 호출한 배열에서 원하는 조건의 요소들만을 담은
새 배열을 반환해 줄 수 있다.

map( )이랑 사용법이 매우 비슷해보이는데
return에 조건을 주면 해당 조건에 만족하는 요소만을 담은
배열을 반환해준다.


14) reduce()

let num = [1, 2, 3, 4, 5];
let result = num.reduce(function(sum, elt, i, array) {
	return sum + elt;
}, 0);
console.log(result);	//결과  15

reduce( ) 메서드는 배열의 요소들에 특정한 처리를 해서
하나의 값으로 반환하는 메서드이다.

위의 예제는 sum에 모든 배열의 요소를 더해서 반환한다.
더하는게 아니라 sum을 다른 이름으로 바꾸더라도
결과적으로 function의 첫 번째 인자를 반환하니
인자 이름은 원하는대로 변경해도 상관없다.

function의 닫는 중괄호 옆의 0은 function의 첫 번째 인자값의 초기값으로
기본은 0으로 설정되어 있다.
만약 30부터 시작하고 싶다면 30으로 바꿔주면 된다.


15) every()

let num = [1, 2, 3, 4, 5];
let result = num.every(function(elt, i, array) {
	return elt <= 4;
});
console.log(result);	//결과 false

every( ) 메서드는 주어진 조건을 모두 만족할 경우 true
하나라도 만족하지 못할 경우 false를 반환하는 메서드이다.

위의 예제에서는 모든 요소가 4보다 작느냐를 조건으로 주었다.
5가 4보다 크니 모든 요소가 조건을 만족하지 못하기에 false를 반환한다.

let num = [1, 2, 3, 4, 5];
let result = num.every(function(elt, i, array) {
	return elt <= 5;
});
console.log(result);	//결과 true

조건을 모든 요소가 5보다 작느냐로 바꾸면
모든 요소가 조건을 만족하여 true를 반환한다.


16) some()

let num = [1, 2, 3, 4, 5];
let result = num.some(function(elt, i, array) {
	return elt % 5 == 0;
});
console.log(result);	//결과 true

some( ) 메서드는 주어진 조건이 하나라도 만족한다면 true
하나도 만족하지 못한다면 false를 반환한다.

위의 예제는 5로 나눈 나머지가 0인 수
즉, 5의 배수인 숫자가 하나라도 있느냐 물어보는 예제이다.

5의 배수인 5가 1개 존재하여 하나라도 조건을 만족하기에
true를 반환한다.


17) indexOf()와 lastIndexOf()

let fruits = ["Orange", "Banana", "Grape", "Apple"];
console.log( fruits.indexOf("Grape") );	//결과 2
console.log( fruits.indexOf("Kiwi") );	//결과 -1

indexOf( ) 메서드는 배열에 찾는 요소가 존재한다면
해당 요소의 인덱스를 반환하고, 없다면 -1을 반환하는 메서드이다.

let fruits = ["Orange", "Banana", "Grape", "Banana"];
console.log( fruits.indexOf("Banana") );	//결과 1
console.log( fruits.indexOf("Banana", 2) );	//결과 3

만약 배열에 찾는 요소가 여러개 존재한다면
앞에 있는 요소의 인덱스를 반환한다.
indexOf에 찾는 요소 뒤에 정수 인자를 하나 더 주어
찾기 시작할 index값을 주면 해당 인덱스부터 찾을 수도 있다.
위의 예제에서 인덱스 2부터 Banana를 찾으면 결과가 3으로 나온다.

let fruits = ["Orange", "Banana", "Grape", "Banana"];
console.log( fruits.lastIndexOf("Grape") );	//결과 2
console.log( fruits.lastIndexOf("Banana") );	//결과 3

lastIndexOf( ) 메서드는 배열에서 원하는 요소를 찾되
배열의 뒤에서부터 찾아 인덱스값을 반환하는 메서드이다.

만약 Banana를 찾을 때 indexOf( )였다면 1을 반환하겠지만
lastIndexOf( )는 뒤에서부터 찾기 때문에 3을 반환해준다.


5. 미분류


이 파트에는 4번 메서드 파트에 분류하기 애매한 내용들을 담았다. 추후 추가적으로 정리될 예정이다.

1) isArray()

let fruits = ["Orange", "Banana", "Apple"];
let num = 3;
console.log(Array.isArray(fruits));	//결과 true
console.log(Array.isArray(num));	//결과 false

자바스크립트에는 배열과 관련된 메서드들이 존재하는
Array 전역객체가 존재한다.

이 전역 객체에는 여러 메서드가 존재하는데
isArray는 인자로 오는 요소가 배열인지 아닌지 판단하여
true, false값을 반환해준다.

typeof로 배열이 맞는지 확인하고 싶어도 object로 나오기 때문에
요소가 배열인지 확인하고 싶을땐 Array.isArray를 사용하면 된다.


2) delete

let fruits = ["Orange", "Banana", "Apple"];
delete fruits[1];
console.log(fruits);	//결과 ["Orange", empty, "Apple"]

delete 배열명[인덱스]를 통해서 해당 배열의 인덱스 요소를
지울 수 있다.
하지만 공간 그 자체를 없애버리는게 아니라 empty,
즉 undefined로 공간은 남아있게 되어버린다.

그래서 delete로 요소를 지워도 배열의 길이는 줄어들지 않는다.


3) 배열의 최대값과 최소값

let num = [1, 3, 2, 5, 4];
console.log(Math.max.apply(null, m));
console.log(Math.min.apply(null, m));

Math 전역객체와 apply 메서드를 활용해
배열 내 가장 큰 값과 가장 작은 값을 손쉽게 가져올 수 있다.

0개의 댓글