모던 자바스크립트 (자료구조와 자료형) 3-1. 원시 값 활용과 배열 관련 메서드
원시값을 객체 처럼 사용하기
- 원시값
: string, number, boolean, bigint, symbol, undefined, null
- 객체
: {}로 선언되며 다양한 자료형을 포함할 수 있음
- 래퍼객체
: 원시값 그대로의 값을 유지하되 문자열, 숫자, 불린, 심볼의 메서드와 프로퍼티에 접근할 수 있도록
언어 차원에서 허용한 객체
- 원시 래퍼 객체
: 원시값이 메서드나 프로퍼티에 접근하기 위해 추가 기능을 제공해주는 특수한 객체
: 이 객체는 곧 삭제됨
let str = "Hello";
alert( str.toUpperCase() ); // HELLO
let n = 1.23456;
alert( n.toFixed(2) ); // 1.23
배열 요소 제어
- arr.push(...items)
: 맨 끝에 요소 추가
- arr.pop()
: 맨 끝 요소 제거
- arr.shift()
: 맨 앞 요소 제거
- arr.unshift(...items)
: 맨 앞에 요소 추가
splice()
: 배열의 기존 요소를 삭제 또는 교체 하거나 새 요소를 추가하는 메서드
arr.splice(index[, deleteCount, elem1, ..., elemN])
// 배열 요소 제거
let arr = ["I", "study", "JavaScript", "right", "now"];
// 처음 두 개의 요소를 삭제함
let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- 삭제된 요소로 구성된 배열
// 배열 요소 교체
let arr = ["I", "study", "JavaScript", "right", "now"];
// 처음(0) 세 개(3)의 요소를 지우고, 이 자리를 다른 요소로 대체합니다.
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // now ["Let's", "dance", "right", "now"]
// 배열 요소 추가
let arr = ["I", "study", "JavaScript"];
// 인덱스 2부터
// 0개의 요소를 삭제합니다.
// 그 후, "complex"와 "language"를 추가합니다.
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"
// 음수 인덱스
let arr = [1, 2, 5];
// 인덱스 -1부터 (배열 끝에서부터 첫 번째 요소)
// 0개의 요소를 삭제하고
// 3과 4를 추가합니다.
arr.splice(-1, 0, 3, 4);
alert( arr ); // 1,2,3,4,5
slice()
: 어떤 배열의 begin 부터 end까지 (end 미포함) 얕은 복사본을 새로운 배열로 반환
: splice와 달리 서브 문자열이 아닌 서브 배열이 반환됨
arr.slice([start], [end])
let arr = ["t", "e", "s", "t"];
alert( arr.slice(1, 3) ); // e,s (인덱스가 1인 요소부터 인덱스가 3인 요소까지를 복사(인덱스가 3인 요소는 제외))
alert( arr.slice(-2) ); // s,t (인덱스가 -2인 요소부터 제일 끝 요소까지를 복사)
concat()
: 기존 배열의 요소를 사용해 새로운 배열을 만들거나 기존 배열애 추가하는 메서드
: 객체를 복사할 경우 통째로 복사됨
: 특수한 프로퍼티가 요소로 있는 경우 객체를 배열처럼 취급
arr.concat(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
let arr = [1, 2];
let arrayLike = {
0: "something",
length: 1
};
alert( arr.concat(arrayLike) ); // 1,2,[object Object]
let arr = [1, 2];
let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2
};
alert( arr.concat(arrayLike) ); // 1,2,something,else
forEach()
: 배열의 요소를 꺼내어 반복 작업 시행
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
alert(`${item} is at index ${index} in ${array}`);
});
배열 탐색하기
- arr.indexOf(item, from)
: 인덱스 from부터 시작해 item(요소)을 탐색
: 요소를 발견하면 해당 요소의 인덱스를 반환하고, 발견하지 못했으면 -1을 반환
- arr.lastIndexOf(item, from)
: 위 메서드와 동일한 기능을 하는데, 검색을 끝에서부터 시작한다는 점만 다름
- arr.includes(item, from)
: 인덱스 from부터 시작해 item이 있는지를 검색하는데, 해당하는 요소를 발견하면 true를 반환
: NaN도 제대로 처리
- find()
: 객체로 이루어진 배열에서 특정 조건에 부합하는 객체를 배열 내에서 탐색
: item = 함수를 호출할 요소
: index = 요소의 인덱스
: array = 배열 자기 자신
let result = arr.find(function(item, index, array) {
// true가 반환되면 반복이 멈추고 해당 요소를 반환합니다.
// 조건에 해당하는 요소가 없으면 undefined를 반환합니다.
});
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
- findIndex()
: find와 용법은 같으나 인덱스 혹은 -1이 반환됨
- filter()
: 함수의 반환 값을 true로 만드는 단 하나의 요소를 탐색하여 배열로 반환
: 조건을 충족하는 요소가 여러개 라면 find 대신 사용
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
배열을 변형하는 메서드
- map()
: 배열 전체요소를 대상으로 함수를 호출하고 호출 결과를 배열로 반환
let result = arr.map(function(item, index, array) {
// 요소 대신 새로운 값을 반환합니다.
});
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
- sort()
: 배열의 요소를 정렬. 배열 자체가 변경됨
: 요소는 문자열로 취급되어 정렬됨
: 포괄적인 정렬 알고리즘을 사용 (주로 퀵소트 사용)
let arr = [ 1, 2, 15 ];
// arr 내부가 재 정렬됩니다.
arr.sort();
alert( arr ); // 1, 15, 2
// 오름차순 기준으로 정렬
function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
let arr = [ 1, 2, 15 ];
arr.sort(compareNumeric);
alert(arr); // 1, 2, 15
// 요소간의 비교 확인
[1, -2, 15, 2, 0, 8].sort(function(a, b) {
alert( a + " <> " + b );
return a - b;
});
- localeCompare()
: 문자열 정렬
let countries = ['Österreich', 'Andorra', 'Vietnam'];
alert( countries.sort( (a, b) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich (제대로 정렬이 되지 않았습니다.)
alert( countries.sort( (a, b) => a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (제대로 정렬되었네요!)
- reverse()
: 역순으로 배열을 정렬
let arr = [1, 2, 3, 4, 5];
arr.reverse();
alert( arr ); // 5,4,3,2,1
split()
: 구분자를 기준으로 문자열을 쪼개서 배열로 반환
let names = 'Bilbo, Gandalf, Nazgul';
let arr = names.split(', ');
for (let name of arr) {
alert( `${name}에게 보내는 메시지` ); // Bilbo에게 보내는 메시지
}
// 글자단위로 분리
let str = "test";
alert( str.split('') ); // t,e,s,t
join()
: 배열 요소를 합쳐서 문자열로 반환
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = arr.join(';'); // 배열 요소 모두를 ;를 사용해 하나의 문자열로 합칩니다.
alert( str ); // Bilbo;Gandalf;Nazgul
reduce()
: map과 비슷한 기능을 하지만 배열을 기반으로 값 하나를 도출
: 좌측에서 부터 값을 더해서 계산
- accumulator : 이전 함수 호출의 결과. initial은 함수 최초 호출 시 사용되는 초깃값을 나타냄(옵션)
- item : 현재 배열 요소
- index : 요소의 위치
- array : 배열
let value = arr.reduce(function(accumulator, item, index, array) {
// ...
}, [initial]);
// 배열 요소의 합
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((sum, current) => sum + current, 0);
alert(result); // 15
// 배열 요소의 합 (초기 값 제거)
let arr = [1, 2, 3, 4, 5];
// reduce에서 초깃값을 제거함(0이 없음)
let result = arr.reduce((sum, current) => sum + current);
alert( result ); // 15
reduceRight()
: reduce와 동일한 기능을 하지만 우측에서 부터 합산 수행
배열 판단
- array.isArray()
alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
thisArg
: sort를 제외한 배열 메서드에서 사용 가능한 옵션 매개변수
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg는 선택적으로 사용할 수 있는 마지막 인수입니다.
let army = {
minAge: 18,
maxAge: 27,
canJoin(user) {
return user.age >= this.minAge && user.age < this.maxAge;
}
};
let users = [
{age: 16},
{age: 20},
{age: 23},
{age: 30}
];
// army.canJoin 호출 시 참을 반환해주는 user를 찾음
let soldiers = users.filter(army.canJoin, army);
alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23
some()
: 배열 내 모든 요소에 대하여 함수의 반환 값을 true로 만드는 요소가 하나라도 있는지 확인
: 반환 값은 boolean
every()
: 배열 내 모든 요소가 함수의 반환 값을 true로 만드는지 확인
: 반환 값은 boolean
fill(value, start, end)
: 배열의 start 부터 end까지 value를 채워 넣음
copyWithIn(target, start, end)
: start 부터 end까지 요소를 복사하고 target에 붙혀넣기
Refference
https://ko.javascript.info/primitives-methods
https://ko.javascript.info/array-methods