
순서가 있는 컬렉션을 저장할 때 쓰는 자료구조인 배열을 알아보자
let arr = new Array();
let arr = [];
예시
let fruits = ["사과", "오렌지", "자두"];
fruits[2] = '배'; // 배열이 ["사과", "오렌지", "배"]로 바뀜
fruits[3] = '레몬'; // 배열이 ["사과", "오렌지", "배", "레몬"]으로 바뀜
배열 요소 길이 확인 (length 사용)
let fruits = ["사과", "오렌지", "자두"];
alert( fruits.length ); // 3
// 요소에 여러 가지 자료형이 섞여 있습니다.
let arr = [ '사과', { name: '이보라' }, true, function() { alert('안녕하세요.'); } ];
// 인덱스가 1인 요소(객체)의 name 프로퍼티를 출력합니다.
alert( arr[1].name ); // 이보라
// 인덱스가 3인 요소(함수)를 실행합니다.
arr[3](); // 안녕하세요.
trailing 쉼표 : 배열의 마지막 요소는 객체와 마찬가지로 쉼표로 끝날 수 있습니다.
배열을 사용해 만들 수 있는 대표적인 자료구조
push : 맨 끝에 요소를 추가한다.
shift : 제일 앞 요소를 꺼내 제거한 후, 남아있는 요소를 앞으로 밀어준다.
unshift : 배열 앞에 요소를 추가한다.- unshift의 예시
let fruits = ["오렌지", "배"];
fruits.unshift('사과');
alert( fruits ); // 사과,오렌지,배
배열엔 두 연산을 가능하게 해주는 내장 메서드
push와pop이 있다.
화면에 순차적으로 띄울 메시지를 비축해 놓을 자료 구조를 만들 때큐를 사용하는 것처럼
큐는 실무에서 상당히 자주 쓰이는 자료구조이다.
배열은 큐 이외에 스택(stack)이라 불리는 자료구조를 구현한다.
push : 요소를 스택 끝에 집어 넣는다.pop : 스택 끝 요소를 추출한다.스택은 이처럼 '한쪽 끝'에 더하거나 뺄 수 있게 해주는 자료구조이다.
스택을 사용하면 가장 나중에 집어넣은 요소가 먼저 나온다. 이런 특징을 LIFO이라 부른다.
반면 큐를 사용하면 먼저 집어넣은 요소가 먼저 나오기 때문에, 이런 특징을 FIFO 자료구조라 부른다.
이렇게 처음이나 끝에 요소를 더하거나 빼주는 연산을 제공하는 자료구조를 데큐라고 부른다.
성능 : push와 pop은 빠르지만 shift와 unshift는 느립니다.
for문은 배열을 순회할때 쓰는 가장 오래된 방법이다.
let arr = ["사과", "오렌지", "배"];
for (let i = 0; i < arr.length; i++) {
alert( arr[i] );
}
배열에 무언가 조작을 가하면 length프로퍼티가 자동으로 갱신된다.
length프로퍼티는 배열 내 요소의 개수가 아니라 가장 큰 인덱스에 1을 더한 값이다.
length프로퍼티의 또 다른 특징은 쓰기가 가능하다는 점이다.
let arr = [1, 2, 3, 4, 5];
arr.length = 2; // 요소 2개만 남기고 잘라봅시다.
alert( arr ); // [1, 2]
arr.length = 5; // 본래 길이로 되돌려 봅시다.
alert( arr[3] ); // undefined: 삭제된 기존 요소들이 복구되지 않습니다.
arr.length = 0;을 사용해 간단하게 배열을 비울 수 있다.let arr = new Array("사과", "배", "기타");
배열 역시 배열의 요소가 될 수 있다. 이런 배열을 다차원 배열이라 부른다.
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
alert( matrix[1][1] ); // 5, 중심에 있는 요소
배열은 특수한 형태의 객체로, 순서가 있는 자료를 저장하고 관리하는 용도이다.
- 선언 방법 :
// 대괄호 (가장 많이 쓰이는 방법임)
let arr = [item1, item2...];
// new Array (잘 쓰이지 않음)
let arr = new Array(item1, item2...);
new Array(number)을 호출하면 길이가 number인 배열이 만들어지는데 이 때 요소는 비어있다.
lenght 프로퍼티는 배열의 길이를 나타내준다. 정확히는 숫자형 인덱스 중 가장 큰 값에 1을 더한 값이다.
length 값을 수동으로 줄이면 배열 끝이 잘린다.
push(...items) – items를 배열 끝에 더해줍니다.
pop() – 배열 끝 요소를 제거하고, 제거한 요소를 반환합니다.
shift() – 배열 처음 요소를 제거하고, 제거한 요소를 반환합니다.
unshift(...items) – items를 배열 처음에 더해줍니다.
배열의 맨 앞이나 끝에 요소를 추가하거나 제거하는 메서드 (push,pop,shift,unshift) 는 위에 학습을 했고 이외 요소 추가와 제거에 관련된 메서드를 알아보자.
배열에서 요소 하나만 지우고 싶다면 배열 역시 객체형에 속하므로 프로퍼티를 지울때는 연산자 delete를 사용할 수 있다.
let arr = ["I", "go", "home"];
delete arr[1]; // "go"를 삭제합니다.
alert( arr[1] ); // undefined
// delete를 써서 요소를 지우고 난 후 배열 --> arr = ["I", , "home"];
alert( arr.length ); // 3
요소를 지우긴 했지만 여전히 배열의 요소는 3개이다.
delete obj.key는 key를 이용해 해당 키에 상응하는 값을 지우기 때문에 요소의 길이가 빈 값으로 남게 되는것이다.
arr.splice(start)는 요소를 자유자재로 다룰 수 있다. 이 메서드를 사용하면 요소 추가, 삭제, 교체 모두 가능하다.
splice 문법
arr.splice(index[, deleteCount, elem1, ..., elemN])
index: 조작을 가할 첫 번째 요소를 가리킨다.deleteCount: 제거하고자 하는 요소의 개수를 나타낸다.elem1, ..., elemN: 배열에 추가할 요소를 나타낸다.
예시
let arr = ["I", "study", "JavaScript"];
arr.splice(1, 1); // 인덱스 1부터 요소 한 개를 제거
alert( arr ); // ["I", "JavaScript"]
1이 가리키는 요소부터 시작해 요소 한 개를 지웠다.요소 세 개를 지우고, 그 자리를 다른 요소 두 개로 교체
let arr = ["I", "study", "JavaScript", "right", "now"];
// 처음(0) 세 개(3)의 요소를 지우고, 이 자리를 다른 요소로 대체합니다.
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // now ["Let's", "dance", "right", "now"]
deleteCount를 0으로 설정해 요소를 제거하지 않고 새로운 요소를 추가
let arr = ["I", "study", "JavaScript"];
// 인덱스 2부터
// 0개의 요소를 삭제합니다.
// 그 후, "complex"와 "language"를 추가합니다.
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"
arr.slice는 arr.splice와 유사해 보이지만 훨씬 간단하다.
slice 문법
arr.slice([start], [end])
"start"인덱스부터 ("end"를 제외한)"end"인덱스 까지의 요소를 복사한 새로운 배열을 반환한다.arr.slice는 문자열 메서드인str.slice와 유사하게 동작하는데arr.slice는 서브 배열을 반환한다.
let arr = ["t", "e", "s", "t"];
alert( arr.slice(1, 3) ); // e,s (인덱스가 1인 요소부터 인덱스가 3인 요소까지를 복사(인덱스가 3인 요소는 제외))
alert( arr.slice(-2) ); // s,t (인덱스가 -2인 요소부터 제일 끝 요소까지를 복사)
arr.slice()는 인수를 하나도 넘기지 않고 arr의 복사본을 만들 수 있다. arr.concat은 기존 배열의 요소를 사용해 새로운 배열을 만들거나 기존 배열에 요소를 추가할때 사용한다.
concat 문법
arr.concat(arg1, arg2...)
- 인수엔 배열이나 값이 오는데, 인수 개수에는 제한이 없다.
- 메서드를 호출시
arr에 속한 모든 요소와arg1,arg2등에 속한 모든 요소를 한곳에 모은 새로운 배열이 반환된다.
let arr = [1, 2];
// arr의 요소 모두와 [3,4]의 요소 모두를 한데 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4]) ); // 1,2,3,4
// arr의 요소 모두와 [3,4]의 요소 모두, [5,6]의 요소 모두를 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6
// arr의 요소 모두와 [3,4]의 요소 모두, 5와 6을 한데 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6
arr.forEach는 주어진 함수를 배열 요소 각각에 실행할 수 있게 해준다.
forEach 문법
arr.forEach(function(item, index, array) { // 요소에 무언가를 할 수 있습니다. });아래는 인덱스 정보까지 더해서 출력해주는 좀 더 정교한 코드이다.
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => { alert(`${item} is at index ${index} in ${array}`); });결과값
1. Bilbo is at index 0 Bilbo,Gandalf,Nazgul
2. Gandalf is at index 1 Bilbo,Gandalf,Nazgul
3. Nazgul is at index 2 Bilbo,Gandalf,Nazgul
특정 조건에 부합하는 객체를 배열 내에서 찾는 방법(arr.find(fn))이다.
find와 문법
let result = arr.find(function(item, index, array) { // true가 반환되면 반복이 멈추고 해당 요소를 반환합니다. // 조건에 해당하는 요소가 없으면 undefined를 반환합니다. });
item: 함수를 호출할 요소index: 요소의 인덱스array: 배열 자기 자신
함수가 참을 반환하면 탐색은 중단되고, 해당 요소가 반환된다.
원하는 요소를 찾지 못했으면 undefined가 반환된다.
id와 name 프로퍼티를 가진 사용자 객체로 구성된 배열을 예로 들어보자.
(배열 내에서 id==1조건을 충족하는 사용자 객체를 찾는다.)
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
let user = users.find(item => item.id == 1);
alert(user.name); // John
(item => item.id == 1).이런 패턴이 가장 많이 사용되는 편이며, 다른 인자들(index, array)은 잘 사용되지 않는다.
arr.findIndex는 find와 동일한 일을 하나, 조건에 맞는 요소를 반환하는 대신 해당 요소의 인덱스를 반환한다는 점이 다르다.
-1이 반환된다.find메서드는 함수의 반환 값을 true로 만드는 단 하나의 요소를 찾는데, 조건을 충족하는 요소가 여러 개라면 arr.filter(fn)을 사용한다.filter 문법
let results = arr.filter(function(item, index, array) { // 조건을 충족하는 요소는 results에 순차적으로 더해집니다. // 조건을 충족하는 요소가 하나도 없으면 빈 배열이 반환됩니다. });
예시
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
// 앞쪽 사용자 두 명을 반환합니다.
let someUsers = users.filter(item => item.id < 3);
alert(someUsers.length); // 2
배열을 변형시키거나 요소를 재 정렬해주는 메서드이다.
arr.maap은 유용성과 사용 빈도가 아주 높은 메서드 이다.
map은 배열 요소 전체를 대상으로 함수를 호출하고, 함수 호출 결과를 배열로 반환한다.
map함수 문법:let result = arr.map(function(item, index, array) { // 요소 대신 새로운 값을 반환합니다. });
문자열의 길이를 출력해주는 예시
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
arr.sort()는 배열의 요소를 정리해준다. (배열 자체가 변경된다.)
let arr = [ 1, 2, 15 ];
// arr 내부가 재 정렬됩니다.
arr.sort();
alert( arr ); // 1, 15, 2
1,2,15)와는 다르게 출력된다.arr.reverse는 arr의 요소를 역순으로 정렬시켜주는 메서드이다.
let arr = [1, 2, 3, 4, 5];
arr.reverse();
alert( arr ); // 5,4,3,2,1
자바스크립트에서 배열은 객체형에 속한다.
따라서 typeof로는 일반 객체와 배열을 구분할 수가 없다.
alert(typeof {}); // object
alert(typeof []); // object
그런데 배열은 자주 사용되는 자료구조라 감별 할 수 있는 메서드가 있다면 아주 유용하다.
Array.isArray(value)는 이럴 때 사용할 수 있는 메서드이다.
value가 배열이라면 true를, 배열이 아니라면 false를 반환한다.alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
push(...items) : 맨 끝에 요소 추가
pop() : 맨 끝에 요소 추출
shift() : 첫 요소 추출
unshift(...items) : 맨 앞에 요소 추가
splice(pox, deleteCount, ...items) : pos부터 deleteCount개의 요소를 지우고, items 추가
slice(start, end) : start부터 end바로 앞까지 요소를 복사해 새로운 배열 만듬
concat(...items) : 배열 모든 요소를 복사, items를 추가해 새로운 배열을 만든 후 이를 반환.
indexOf/lastIndexOf(item,pos) : pos부터 원하는 item을 찾는다. 찾게 되면 해당 요소의 인덱스를, 아니면 -1을 반환
includes(value) : 배열에 value가 있으면 true를, 그렇지 않으면 false를 반환
find/filter(func) : func의 반환 값을 true로 만드는 첫 번재/전체 요소를 반환
findIndex : find와 유사. 다만 요소 대신 인덱스를 반환
forEach(func) : 모든 요소에 func을 호출 > 결과는 반환되지 않음map(func) : 모든 요소에 func를 호출 > 반환된 결과를 가지고 새로운 배열을 만듬
sort(func) : 배열을 정렬 > 정렬된 배열을 반환
reverse() : 배열을 뒤집어 반환
split/join : 문자열을 배열로, 배열을 문자열로 변환
reduce(func, initial) : 요소를 차례대로 func을 호출 > 반환값은 다음 함수 호출에 전달 > 최종적으로 하나의 값이 도출
Array.isArray(arr) : arr이 배열인지 여부를 판단(true, false)
sort,reverse,splice는 기존 배열을 변형시키는 점에서 주의하기
arr.some(fn)과 arr.every(fn)는 배열을 확인한다.
두 메서드는 map과 유사하게 모든 요소를 대상으로 함수 호출을 한다.
some은 함수 반환값을 true로 만드는 요소가 하나라도 있는지 확인하고
every는 모든 요소가 함수 반환값을 true로 만드는지 여부를 확인한다.
두 메서드 모두 조건을 충족하면 true, 그렇지 않으면 false를 반환.
arr.fill(value,start,end)는 start부터 end까지 value를 채워 넣는다.
arr.copyWithin(target,start,end)는 start부터 end까지 요소를 복사 > 복사한 요소를 target에 붙여넣는다. (기존 요소가 있다면 덮어 씌운다)