
데이터들을 차례대로 나열하여 하나로 묶은 데이터의 집합.
// 오늘의 사골국이 될 배열 예시코드
["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
javaScript에서 데이터를 묶음으로 관리할 수 있는 도구로 배열과 객체가 있다.
객체는 데이터에 이름을 붙여 데이터 덩어리에서 쉽게
원하는 데이터를 꺼내쓸 수 있는 굉장히 멋진 도구이지만
데이터의 순서라는 개념은 객체에 없다.
따라서 데이터를 순서대로 주거나 받아야 할 경우에는
객체를 쓸 수 없다.
하지만 배열은 데이터가 담긴 순서를 기억한다!
객체처럼 데이터의 이름을 내가 정할 수는 없지만
데이터마다 자동으로 index가 붙기에 이것을 활용하여
순서를 바탕으로 데이터를 다룰 수도 있고
담긴 데이터를 순회하면서 데이터를 확인하기도 편리하며
또한 데이터가 어떤 순서대로 받아졌는지 쉽게 알 수 있는 등등
array는 데이터 덩어리에 순서가 필요한 경우 적격이다.
배열은 다음과 같은 내용으로 구성되어 있다.
element의 길이는 배열을 담은
변수명.length로 알아볼 수 있으며 element의 총 갯수를 표시한다.let 훈련소 = ["우로번호!", 1, 2, "👏짝!!", "...🤭", "엎드려."]; console.log(훈련소.length); // 6
["우로번호!", 1, 2, "👏짝!!", "...🤭", "엎드려."];
// "👏짝!!"의 index는 3이다.
["우로번호!", 1, 2, "👏짝!!", "...🤭", "엎드려."];
// "👏짝!!"의 음수 index는 -3이다. -2가 아니다.
index는 색인이라는 뜻이고 색인의 정의는:
"책 속의 내용 중에서 중요한 단어나 항목, 인명 따위를 쉽게 찾아볼 수 있도록 일정한 순서에 따라 별도로 배열하여 놓은 목록."이다.
🤗 사용하는 어휘의 의미에는 의도가 담겨있으니 한번씩 확인해 보는 것도 좋다.
✔️ 변수를 선언하고 대입연산자 =를 넣는다.
let 훈련소 =
✔️ 배열을 의미하는 []를 넣는다.(🤗 ;는 코드의 끝임을 표시하는 기호)
let 훈련소 = [];
✔️ []안에 데이터(요소, element)를 채워 넣는다.
✔️ element와 element는 ,로 구분한다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
✔️ 배열을 담은 변수명 [element의 index]의 형태로 element에 접근할 수 있다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
console.log(훈련소[0], 훈련소[3], 훈련소[5]);
// "우로번호!"
// "👏짝!!!"
// "엎드려."
✔️ 배열을 담은 변수명 . push(추가할 element)의 형태로 배열 끝에 element를 추가할 수 있다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!", "...🤭", "엎드려."];
훈련소.push("하나에 정신");
console.log(훈련소);
// ["우로번호!", 1, 2, "👏짝!!", "...🤭", "엎드려.", "하나에 정신"]
element의 추가는 꼭 배열의 끝에만 할 수 있는 것은 아니다.
이어 나올 삭제도 마찬가지다.
이 부분은 이후 소개할 배열의 메서드 부분에서 추가로 설명하겠다.
✔️ 배열을 담은 변수명 [index] = 대체할 내용의 형태로 특정 element를 수정할 수 있다.
✔️ 변수의 값을 재할당 하는 방법과 거의 같다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
훈련소[3] = 3;
훈련소[4] = "4 번호끝!";
훈련소[5] = "그래 오늘하루 수고들 했다👍";
console.log(훈련소);
// ["우로번호!", 1, 2, 3, "4 번호끝!", "그래 오늘하루 수고들 했다👍"]
✔️ 배열을 담은 변수명 . pop()의 형태로 배열 끝 element를 삭제할 수 있다.
✔️ 제거 후 제거한 element를 반환한다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!", "...🤭", "엎드려."];
// pop()을 세번 써서 시간을 거슬러 올라가 보겠다.
// 참고로 jsbin에서 실행하면 pop-up이 안떠서 반환을 확인할 수 없다.
alert(훈련소.pop()); // pop-up으로 "엎드려."가 뜬다.
alert(훈련소.pop()); // pop-up으로 "...🤭"."가 뜬다.
alert(훈련소.pop()); // pop-up으로 "👏짝!!"가 뜬다.
console.log(훈련소);
// ["우로번호!", 1, 2]
✔️ 배열의 길이와 index
앞서 배열의 길이와 index는 다르다고 설명했다.
index는 항상 배열의 길이보다 1이 적다는 불변의 법칙이 있다.
이 법칙과 이번에 배운 배열의 길이를 구하는 방법,
그리고 element에 접근하는 방법을 조합하면
배열의 길이를 수고스럽게 매번 확인할 필요 없이
배열의 길이가 달라져도 항상 맨 끝에 있는 element를 가져올 수 있다.let 훈련소1 = ["우로번호!", 1, 2, "👏짝!!!"]; console.log(훈련소1[훈련소1.length -1]); // "👏짝!!!" // 배열의 길이가 달라졌지만 똑같은 코드로 배열의 가장 끝 element를 가져왔다! let 훈련소2 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]; console.log(훈련소2[훈련소2.length -1]); // "엎드려."
배열은 모든 데이터 타입을 수용한다.
따라서 배열 안에 배열과 같은 형태 또한 존재할 수 있다.
["엎드려", ["하나에 정신", "둘에 통일", "하나"], "흐아나!!🤮"]
✔️ 배열 안에 배열은 그 안에 element 갯수와 상관 없이 기준이 되는 배열에서 1개의 element로 평가된다.
✔️ 아래와 같은 형태를 중첩배열(2차원 배열)이라고 한다.
여기서는 가독성을 위해 1차원과 2차원으로 나누어 설명하겠다.
let 훈련소 = ["엎드려", ["하나에 정신", "둘에 통일", "하나"], "흐아나!!🤮"];
console.log(훈련소.length); // 3

✔️ 1차원배열처럼 변수명 [2차원배열의 index]로 접근하는 경우 해당 배열 자체를 불러온다.
let 훈련소 = ["엎드려", ["하나에 정신", "둘에 통일", "하나"], "흐아나!!🤮"];
console.log(훈련소[1]); // ["하나에 정신", "둘에 통일", "하나"]
✔️ 1차원배열의 element에 접근하는 방법은 아주아주 간단하다.
변수명 [2차원배열의 index] [2차원배열 속 element의 index]
그냥 []하나를 더 붙이고 그 안에 2차원 배열에서 원하는 element의 index를 써 넣으면 된다.
let 훈련소 = ["엎드려", ["하나에 정신", "둘에 통일", "하나"], "흐아나!!🤮"];
console.log(훈련소[1][0]); // "하나에 정신"
✔️ 배열이 아닌 개별 element data type 그대로를 반환했다.

배열은 method를 이용해서 다양한 조작을 할 수 있다.
곧 소개할 배열 전용 method들 처럼 특정 자료형을 조작하기 위한
전용 공구와 같은 method들도 있다.
method란 객체의 프로퍼티(property)에 할당된 함수다.
(🤗 property는 객체의 key:value를 말한다. 이런 식으로끝 없이
이어지게 되니 지금은 느낌만 가져가자)
❗️포인트는 method는 함수고 함수는 어떤 기능을 한다는 것이다.
그리고 alert(모든자료형)처럼 공통된 method들이 있으며
특정 자료형에서만 사용하는 method들이 따로 있다.
method는 보통 변수명 . method이름()의 형태로 사용한다.
()에는 method마다 들어가는 내용이 다르다.
아래는 배열에서만 사용하는 method들이다.
(이미 예시에서 사용한 push()와 pop()은 제외하겠다.)
❗️이어질 예시에서
method()의()안에 argument(인수)는 필수조건이고[]안의 argument는 부가(option)조건이다.
splice(필수조건[, 부가조건, 부가조건])
또한 예시에 method의()에 넣는 element는 넓은 의미로 함수의 argument이기도 하기 때문에 혼용하며 사용할 수도 있지만 같은 의미다.
🤗 혹시 method가 왜 함수인지 궁금하신 분들을 위해 method의 구성을 살펴보겠다.// 객체의 property로 함수를 할당 let 객체 = { // property가 함수일 경우 property면서 동시에 method가 된다. // ES6부터 함수명(parameter) {...}으로 단축구문 사용 가능. 함수명:function(paremeter) {...} } // method 호출 객체.함수명(argument);
각각 추가, 삭제를 하면서 ❗️기존 배열을 변형시킨다.
✔️ 배열 첫번째 element를 제거하고 제거한 element를 반환한다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
alert(훈련소.shift()); // pop-up으로 "우로번호"!가 반환된다.
console.log(훈련소); // [1, 2, "👏짝!!!", "...🤭", "엎드려."]
console.log(훈련소[0]) // 1
✔️ 배열 첫번째에 element를 추가한다.
✔️ 여러개를 추가할수도 있다.(push()도 마찬가지)
✔️ argument에 추가하고 싶은 element를 넣는다.
let 훈련소 = [1, 2, "👏짝!!!", "...🤭", "엎드려."];
훈련소.unshift("우로번호!", "🕺");
console.log(훈련소); // ["우로번호!", "🕺", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
// 돌아온 우로번호
console.log(훈련소[0]) // "우로번호!"
✔️ 배열에서 element를 추가, 삭제, 교체 모두 가능!
✔️ 따라서 ❗️기존 배열을 변형시킨다.
✔️ 삭제시 삭제된 element로 구성된 배열을 반환된다.
✔️ argument 설명
index를 포함하여 deleteCount에 적은 숫자만큼 오른쪽 방향으로 element를 삭제한다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
// index 1 포함 2개 삭제
console.log(훈련소.splice(1, 2)); // [1, 2] 반환
console.log(훈련소); // ["우로번호!", "👏짝!!!", "...🤭", "엎드려."]
element 삭제하는 방법에서 넣고싶은 element만 추가하면 된다.
삭제한 자리에 추가한 순서대로 새로운 element가 추가된다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
// index 3 포함 3개 삭제 후 그 자리에 2개의 새로운 element 추가.
// 앞서 설명한 것 처럼 index는 음수로 표시할 수도 있다.
console.log(훈련소.splice(-3, 3, 3, "총원 3명 이상무!", "오늘도 수고했다👍"));
// ["👏짝!!!", "...🤭", "엎드려."] 반환
console.log(훈련소);
// ["우로번호!", 1, 2, 3, "총원 3명 이상무!", "오늘도 수고했다👍"]
deleteCount를 0으로 하면 element삭제 없이 추가만 할 수 있다.
let 훈련소 = ["👏짝!!!", "...🤭", "엎드려."];
// 삭제 없이 0번 index부터 새로운 element 추가.
console.log(훈련소.splice(0, 0, "우로번호!!", 1, 2)); // [] 반환
console.log(훈련소);
// ["우로번호!!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
✔️ startIndex부터 endIndex "앞"까지의 element를 복사하여 기존 배열을 건드리지 않고 ❗️새로운 배열을 반환한다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
console.log(훈련소.slice(0, 3)); // ["우로번호!", 1, 2]
// 원본 배열에는 아무 변화가 없다.
console.log(훈련소);
// ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
let 짝 = 훈련소.slice(0, 3);
// 복사한 element들로 새로운 배열을 만들 수 있다.
console.log(짝) // ["우로번호!", 1, 2]
✔️argument 자리를 비워두면 배열을 그대로 복사해서 동일한 새로운 배열을 반환하기 때문에 상황에 따라 유용하다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
// argument를 비워놨다.
let 짝 = 훈련소.slice();
// 원본 배열을 그대로 복사한 ❗️새로운 배열을 반환했다.
console.log(짝);
// ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
// 원본은 변함이 없다!
console.log(훈련소);
// ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
✔️ 기존 배열을 복사해 ❗️새로운 배열을 반환한다.
✔️ 기존 배열에 argument를 추가한 새로운 배열을 반환할 수 있다.
✔️ slice()와 마찬가지로 ()를 비워두면 기존배열 그대로를 복사/반환한다.
let 훈련소 = ["우로번호!", 1, 2];
let 우당탕훈련소 = 훈련소.concat("👏짝!!!", "...🤭", "엎드려.");
console.log(훈련소); // ["우로번호!", 1, 2]
console.log(우당탕훈련소);
//["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
✔️ argument로 바로 element를 넣어줄수도 있고, 배열이 할당된 변수를 넣어서 줄수도있다.
✔️ argument가 배열인 경우
let 훈련소 = ["우로번호!", 1, 2];
// 직접 넣기
let 직접1차원훈련소 = 훈련소.concat(3, 4);
let 직접2차원훈련소 = 훈련소.concat(3, [[4, 5]<]);
let 직접3차원훈련소 = 훈련소.concat(3, [[4, 5, [6, 7]]]);
console.log(직접1차원훈련소, 직접2차원훈련소, 직접3차원훈련소);
// 간접 넣기
let 간접1차원 = [3, 4];
let 간접2차원 = [3, [4, 5]];
let 간접3차원 = [3, [4, 5, [6, 7]]];
let 간접1차원훈련소 = 훈련소.concat(간접1차원);
let 간접2차원훈련소 = 훈련소.concat(간접2차원);
let 간접3차원훈련소 = 훈련소.concat(간접3차원);
console.log(간접1차원훈련소, 간접2차원훈련소, 간접3차원훈련소);
/* 결과는 직접과 간접 둘 다 같음
[ '우로번호!', 1, 2, 3, 4 ]
[ '우로번호!', 1, 2, 3, [ 4, 5 ] ]
[ '우로번호!', 1, 2, 3, [ 4, 5, [ 6, 7 ] ] ]
*/
❗️배열 1개를 합칠 때는 구분이 쉽지만
concat()의 argument로 직접 배열을 넣게된다면 헷갈릴 수 있으니 주의해야 한다.
concat()은 argument로 넣은 데이터에[]가 없으면 그대로 1개의 element로 인식하여 합치며, 1차원 배열 까지는 1개의 배열로 합친다.let a = [1, 2] // 왼쪽부터 1차원 1차원 2차원 console.log(a.concat(3, [4], [5, [6]])) // [1, 2, 3, 4, 5, [6]]
✔️ argument가 객체인경우 객체(유사배열 객체를 포함) 그대로가 복사된다.
let 훈련소 = ["우로번호!", 1, 2];
let 우당탕 = {
0: "👏짝!!!",
1: "...🤭",
2: "엎드려.",
}
let 우당탕훈련소 = 훈련소.concat(우당탕);
console.log(우당탕훈련소);
// ["우로번호!", 1, 2, [object Object]]
이 경우 유사배열 객체 끝에 [Symbol.isConcatSpreadable]: true,와 length: 유사배열 길이를 넣으면 concat()이 객체의 propery를 배열로 인식하고 하나의 배열로 합쳐 반환한다.
let 훈련소 = ["우로번호!", 1, 2];
let 우당탕 = {
0: "👏짝!!!",
1: "...🤭",
2: "엎드려.",
[Symbol.isConcatSpreadable]: true,
length: 3
}
let 우당탕훈련소 = 훈련소.concat(우당탕);
console.log(우당탕훈련소);
//["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]
slice()와concat()의
- 공통점: 원본 배열을 변형시키지 않고 새로운 배열을 반환한다.
- 차이점:
slice()는 원본 배열에서 일부 element를 제외한 배열을 가져올 수 있고,concat()은 원본 배열에 element를 추가하는 기능이 있다.
✔️ forEach()는 배열을 순회하며 각각의 element들에게 차례대로 주어진 함수를 호출(적용)한다.(🤗 함수 === 기능이나 마찬가지이므로 element들에 하나씩 기능(함수)을 실행시켜준다고 자연스레 생각하자.)
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
훈련소.forEach((item) => console.log(item));
// console창에 각각의 element가 "따로" 출력된다.
✔️ 각각 parameter의 의미는 다음과 같다.
item: 해당 배열을 지목하는것과 동시에 현재 함수 내용을 적용받는 각각의 element들. index: 현재 함수 내용을 적용받는 element의 index.array: 해당 배열 전체.let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
훈련소.forEach((item, index, array) => {
if (index === 3) {
alert(array[3])
} else {
console.log(item)
}
});
// "👏짝!!!"은 pop-up되고 나머지는 console창에 출력된다.
🤗 parameter라고 하는 이유는
() =>가 화살표 함수라고 하는 함수의 또다른 형태이기 때문이다.
따라서()에는 기본 함수와 똑같이 parameter 이름을 자유롭게 지어 사용할 수 있다.
화살표 함수((parameter) => {...})
화살표 함수는 선언(function)과 이름(변수명 혹은 함수명)을 생략할 수 있고 따로return을 쓰지 않아도 적용된다.
parameter가 없으면()를 생략해도 되고 코드가 한줄이면{}도 필요 없다.
작은 함수를 만들어 쓸 때 유용하고 일반 함수와 몇몇 동작이 다르다.
(지금은 배열을 알아보는 시간이므로 여기까지만.)
✔️ forEach()는 함수를 실행하고 결과값을 return하지는 않는다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
let a = 훈련소.forEach((item, index) => item += `[index: ${index}]`);
console.log(a); // undefined
map()이라는 method는 값을 새로운 배열로 반환해준다.
(🤗 forEach와 함께 비교하며 특성을 이해하자.)let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."]; let a = 훈련소.map((item, index) => item += `[index: ${index}]`); console.log(a); // ['우로번호![index: 0]', '1[index: 1]', '2[index: 2]', '👏짝!!![index: 3]', '...🤭[index: 4]', '엎드려.[index: 5]']
✔️ 값을 return하지 않으면 워따쓰나?? "return"과 "기능"은 다르다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
let 열외 = [];
훈련소.forEach((item) => {
if (item === "👏짝!!!") {
열외.push(item)
}
});
console.log(열외); // "👏짝!!!"
🤗 MDN 등에서 참고자료를 찾다가
method(function(...))으로 표기되어 있는 경우 기본적으로 배열을 순회하면서 element 각각에 함수에 담긴 기능을 실행한다는 공통점을 가지고 있다.
✔️ startIndex부터 일치하는 element를 찾으며, startIndex를 쓰지 않아도 찾는다.
✔️ indexOf()와 lastIndexOf()는 일치하는 element가 있으면 해당 element의 index를 반환하고 없으면 -1을 반환한다.(둘의 차이는 검색을 앞에서부터 하느냐 뒤에서부터 하느냐 뿐이다.)
✔️ includes()는 일치하는 element가 있으면 true를 없으면 false를 반환한다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
// index4에서 -> 방향으로 찾아서 -1(못찾음)이 출력
console.log(훈련소.indexOf("👏짝!!!", 4)); // -1
// index4에서 <- 방향으로 찾아서 찾은 index를 출력
console.log(훈련소.lastIndexOf("👏짝!!!", 4)); // 3
// startIndex를 쓰지 않아도 찾음.
console.log(훈련소.includes("👏짝!!!")); // true
// 일부만 일치하는 경우는 동일한 것이라고 보지 않음.
console.log(훈련소.includes("🤭")); // false
❗️검색하려는 element가 하나의 문자열인 경우, 문자열 일부만 일치하면 동일한 것으로 평가되지 않고 -1이나 false가 출력된다.
✔️ element를 찾을 때 메서드 내부에서 일치연산자===를 사용하기 때문에 자료형까지 정확히 일치해야 index나 true를 반환한다.
let 소지품검사 = [false, 0]
// falsy값인 0은 패스한다.
console.log(소지품검사.indexOf(false)); // 1
✔️ 객체로 이루어진 배열을 대상으로 1개의 element를 찾을 때 사용함.(그냥 배열에도 사용 가능)
✔️ 함수가 true를 반환하면 동작을 멈추고 element를 "본래의 자료형"으로 반환하며, 찾지 못한 경우 undefined를 반환한다.
✔️ findIndex()는 찾는 element가 있으면 index을, 없으면 -1을 반환한다는 점을 제외하면 find()와 똑같다.
let 훈련소 = [
{이름:"전태양", say:"우로번호!"},
{이름:"윤수연", say:1},
{이름:"양가현", say:2},
{이름:"박산성", say:"👏짝!!!"},
{이름:"정경훈", say:"...🤭"},
{이름:"정민지", say:"엎드려."}
];
// method의 함수가 배열을 순회하면서 조건에 맞는 내용을 찾아 true가 되면 반환.
let 좀놀아본사람 = 훈련소.find((item) => item.이름 == "박산성");
alert(좀놀아본사람.say);
객체로 구성된 배열을 실무에서 자주 다룬다고 한다.(예를 들면 json)
하지만 index와 array parameter는 잘 사용하지 않는다고하니 예시 코드를 잘 기억해 놓도록 하자.
✔️ find()와 마찬가지로 객체로 이루어진 배열을 대상으로 사용 가능.
✔️ find()는 1개의 element를 찾고 반환하는 반면, filter()는
조건을 충족하는 모든 element를 담은 "배열"을 반환하고 없으면 빈배열을 반환한다.
let 훈련소 = [
{이름:"전태양", say:"우로번호!"},
{이름:"윤수연", say:1},
{이름:"양가현", say:2},
{이름:"박산성", say:"👏짝!!!"},
{이름:"정경훈", say:"...🤭"},
{이름:"정민지", say:"엎드려."}
];
// 함수가 배열을 순회, 조건에 맞는 내용들을 모두 반환한다.
let 정빠따 = 훈련소.filter((item) => item.이름 == "박산성" || item.이름 == "정민지");
// 배열 안에 객체가 있기 때문에 []과 .으로 순차적으로 접근해봤다.
alert(정빠따[0].say);
alert(정빠따[1].say);
find()와 마찬가지로 객체로 이루어진 배열을 다룰 수 있어 자주 사용할 method 중 하나.
✔️ 배열 전체를 순회하며 각각의 element에게 함수를 호출(적용)하고 변경된 값을 담은 새로운 “배열”을 반환한다.
// map()과 forEach()의 차이
// map() method
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
let a = 훈련소.map((item) => `${item}의 자료형은 ${typeof(item)}입니다.`);
console.log(a);
// ["우로번호!의 자료형은 string입니다.", "1의 자료형은 number입니다.", "2의 자료형은 number입니다.", "👏짝!!!의 자료형은 string입니다.", "...🤭의 자료형은 string입니다.", "엎드려.의 자료형은 string입니다."]
//-----------
// foreEach() method
let 제2훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
let b = 제2훈련소.forEach((item) => `${item}의 자료형은 ${typeof(item)}입니다.`);
// 저장된 값이 없어서 undefined를 반환.
console.log(b); // undefined
forEach()와 언뜻 똑같아 보이지만 결정적차이를 인지해야한다.
❗️forEach()은 실행만을 하고map()은 실행된 값을 반환한다.
✔️ find(), filter()처럼 객체가 담긴 배열을 대상으로도 동작한다.
let 훈련소 = [
{이름:"전태양", say:"우로번호!"},
{이름:"윤수연", say:1},
{이름:"양가현", say:2},
{이름:"박산성", say:"👏짝!!!"},
{이름:"정경훈", say:"...🤭"},
{이름:"정민지", say:"엎드려."},
];
// 훈련소 배열의 element인 객체를 분해해서 재조합했다.
let 짝지 = 훈련소.map((item) => {
let a = {};
// 객체에 외부에서 property를 할당하는 방법. 객체이름[key] = value
a[item.이름] = item.say;
return a;
})
// 배열에 나름대로 재정리한 객체들이 잘 담겨서 돌아왔다.
console.log(짝지);
/* [{ '전태양': '우로번호!' },
{ '윤수연': 1 },
{ '양가현': 2 },
{ '박산성': '👏짝!!!' },
{ '정경훈': '...🤭' },
{ '정민지': '엎드려.' }]
🤗
map()또한 자주 사용하고 유용한 method라고 하니 꼭 익숙해지자.
✔️ sort()는 원본 배열을 정렬하고 정렬된 배열을 반환한다.
✔️ 재정렬된 배열을 반환하긴 하지만 원본 배열이 수정되므로 반환값은 잘 사용하지 않는다.
✔️ sort()는 내부 동작에 대한 이해가 다소 필요하다.
"9" > "1", "Z" > "A"과 같이 사전편집순은 사전 순서의 반대로 사전 뒤쪽 문자일수록 크다고 판단한다."9" > "1"은 문제없어 보일 수 있겠지만 javascript는 문자를 앞에서부터 크기순으로, 동일조건에서는 한 글자라도 긴 문자가 크다고 판단한다.console.log("19" < "9"); // true
console.log("Z" > "A"); // true
console.log("joke" < "joker"); // true
// Unicode 빠월!!
console.log("Joker" < "joker"); // true
✔️ 기본 정렬기준을 쓰지 않고 새로운 기준을 만드려면 sort()에 함수를 넘겨줘야 한다.
let 뒤죽박죽 = [5, 18, 6, 9, 22];
// 뒤죽박죽.sort((a, b) => a - b) 도 가능
function 작은수부터 (a, b) {
return a - b;
}
뒤죽박죽.sort(작은수부터);
// 뒤죽박죽이 차곡차곡이 되었다.
console.log(뒤죽박죽); // [5, 6, 9, 18, 22]
sort()의 argument가 된 함수는 반드시 값 두개를 비교하고 값을 반환해야한다.- 대부분의 숫자 오름차순 정렬은 위의 식을 쓰면 된다.(양쪽의 argument를 비교해서 양수를 반환하면 첫번째 인수가 더 크고 음수를 반환하면 더 작다는 것만 나타내면 된다.)
- 문자열에는 Unicode를 기준으로 글자를 비교해주는
문자.localCompare()를 사용하면 A~Z순으로 정렬 가능하다.let 영어공부 = ["cocoa.", "buy", "alice"]; 영어공부.sort((a, b) => a.localeCompare(b)); // ["alice", "buy", "cocoa."] let 한글공부 = ["다가졌다.", "나만빼고", "김태희는"]; 영어공부.sort((a, b) => a.localeCompare(b)); // ["김태희는", "나만빼고", "다가졌다."]
✔️ 배열의 element를 역순으로 정렬해준다.
let 채연 = ["🥲", "다", "난", "이", "물", "눈", "끔", "ㅏ", "ㄱ", "난"];
채연.reverse();
console.log(채연);
// ["난", "ㄱ", "ㅏ", "끔", "눈", "물", "이", "난", "다", "🥲"]
✔️ split()은 구분자(delimiter)로 구분되어 있는 하나의 문자열 데이터를 해당 구분자를 기준으로 쪼개 나누어 각각이 element가 되어 하나의 배열에 담긴다.
✔️ split()의 argument자리에는 문자열이 구분되어있는(혹은 구분하고 싶은) 형태 그대로를 문자형으로 넣는다.
✔️ 두번째 argument에 숫자를 넣으면 숫자만큼의 쪼개진 문자열만 반환한다.
// "쉼표"와 "띄어쓰기"로 문자들이 구분되어 있다.
let 훈련소 = "우로번호!, 1, 2, 👏짝!!!, ...🤭, 엎드려.";
// argument로 문자열 데이터를 구분짓고 있는 형태와 똑같이 문자열 형식으로 넣는다.
let 쪼개기 = 훈련소.split(", ");
let 반만쪼개기 = 훈련소.split(", ", 3);
// 하나의 문자열이었던 훈련소가 쪼갠대로 나누어진 문자열들을 담은 배열이 되어 돌아왔다.
console.log(쪼개기);
// ["우로번호!", "1", "2", "👏짝!!!", "...🤭", "엎드려."]
console.log(반만쪼개기) // ["우로번호!", "1", "2"]
글자단위로 쪼개려면
split()의 argument를 빈 문자열("")로 지정한다.let 후훗 = "나는강력하다" let 더강해보이게 = 후훗.split(""); console.log(더강해보이게); // ["나", "는", "강", "력", "하", "다"]
✔️ join()은 split()과 반대로 배열의 element를 모두 합쳐 하나의 문자열을 반환한다.
✔️ argument로 넣은 문자열대로 구분표시를 할 수 있으며, 아무것도 넣지 않으면 배열의 구분자 그대로 합쳐진다.
let 훈련소 = ["우로번호!", 1, 2, "👏짝!!!", "...🤭", "엎드려."];
let 내문자열이되라 = 훈련소.join();
console.log(내문자열이되라); // "우로번호!,1,2,👏짝!!!,...🤭,엎드려."
let 내문자열이되라2 = 훈련소.join("-> ");
console.log(내문자열이되라2); // "우로번호!-> 1-> 2-> 👏짝!!!-> ...🤭-> 엎드려."
console.log(typeof(내문자열이되라)) // string
▶︎ 특징별 method 분류
❗️ (기존배열 변형 없이)새로운 배열을 반환:
slice(),concat(),map()
(split()은 "문자열"을 통해 새로운 배열을 반환함)
❗️ 기존 배열을 변형시킴:splice(),sort(),revers(),unshift()/shift(),push()/pop()
✔️ 모든 element에 함수를 호출하는 method:forEach(),map()
✔️ index를 반환:indexOf()/lastIndexOf(),findIndex()
✔️ true/false 관련:includes(),find()/filter()
✔️ 배열에서 무언가 찾음:indexOf()/lastIndexOf(),find()/findIndex(),includes(),filter()
✔️ 객체로 이루어진 배열에서 element를 찾을수 있음:find(),filter()
🌈 작은 회고 🤔
벨로그 쓰는 형식이 조금씩 자리잡는 느낌이 든다.
덕분에 고민 없이 쓰는 부분은 작업속도가 매우매우 빨라졌다.
그렇지만 역시나 배움과 함께 하는 글이기에 후딱 써지지는 않는다.
나를 위하면서도 타인을 위해 글을 쓴다는 것이 매우
어렵다는 것을 한결같이 베베 꼬고있는 몸뚱이가 증명해준다.
부족함이 많은 만큼 고민도 더 많이 생겨서
아직은 나 자신도 이해하기 어려운 부분을 쉽게 설명해보려면
몇글자 쓰고 생각하고 참고자료 찾고 코드쳐보고의 반복이다.
그렇게 오늘도 고생끝에 완성된 하나의 글에 결국 흐믓하다.
하나 하나 쌓인 글 목록을 넘겨보면 그냥 미소가 띄워진다.
자료도 찾다보면 어느덧 안드로메다에 가있던데
회고도 그런것 같다.
제목값을 못하고 주절거리게 된다.
오늘은 그냥 이말을 마지막으로 마무리하고싶다.
같이 열심히 공부하는 여자친구님과 우리 코린이집 햇님반 동료들,
그리고 아직 만나뵌적 없는 동기님들
늘 건강하고 함께 걷는 이 길에 행복만 가득하기를.
덕분에 배열메소드에 대해 잘 알게 된 것 같습니다
정리해주신 덕에 공부에 잘 참고하도록 하겠습니다!
감사합니다 가현님🙇🏻♀️👏