[배열내장함수]
const arr = [1,2,3,4];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
배열내장함수를 사용하면 위 코드를 한 줄로 줄일 수 있다.
내장함수는 객체의 메서드와 같다.
자바스크립트의 자료형은 모두 객체로 이루어져 있다.
arr.forEach((elm) => console.log(elm));
// 파라미터의 *2값을 출력하고 싶다면?
arr.forEach((elm) => console.log(elm *2));
forEach()
내장함수는 배열의 모든 요소를 한 번씩 순회할 수 있도록 해주는 메서드이다.
배열 각각의 요소를 forEach()
내부의 콜백함수에 전달된 파라미터를 한 번씩 순회한다. 쉽게 말해 콜백 함수를 한 요소별로 한번 씩 실행한다.
순회하여 값은 2배로 만들 수 있지만 2배한 값을 배열로 만들진 않는다.
const arr = [1,2,3,4];
const newArr = [];
arr.forEach(function (elm) {
newArr.push(elm *2);
});
console.log(newArr); // [2,4,6,8]
더 짧게 쓴다면, map()
을 사용하면 된다.
map()
은 내부의 콜백함수에 return을 사용할 수 있다.
const arr = [1,2,3,4];
const newArr = arr.map((elm) => {
return elm * 2;
})
console.log(newArr); // [2,4,6,8]
0:2
1:4
2:6
3:8
map()
또한 forEach()
처럼 콜백함수를 순회하지만 return
이 있어서 각각의 값을 반환한다.
map()
은 메모리를 할당하고 리턴 값을 저장, 새로운 array 반환
forEach()
는 리턴 값 X, undefined 반환. 현재 array 반환
const arr = [1,2,3,4];
let number = 3;
arr.forEach((elm) => {
if (elm === numbers) {
console.log(true);
}
})
includes
를 사용하면 연산자를 통해 비교하지 않고 메서드를 사용해 바로 true/false를 확인할 수 있다.
console.log(arr.includes(number));
// true
includes
는 주어진 배열에서 인자가 존재하는지 boolean식으로 확인이 가능하다.
이젠 존재유무에 더해서 몇 번째 인덱스에 존재하는 지 까지 확인하는 메서드가 있는데 이것은 indexOf
이다.
let number = "3";
console.log(arr.indexOf(number));
// -1
결과값이 -1이 나오는 경우는 인자로 존재하지 않는 경우이다.
존재유무를 알 수 있고, 있다면 몇 번째에 위치하는지도 알 수 있게 된다.
하지만, 객체로 이루어진 배열에서는 indexOf
, includes
와 같은 확인 메서드를 사용하기 힘들 수 있다.
const arr = [
{color : "red"},
{color : "black"},
{color : "blue"},
{color : "green"}
];
let number = 3;
객체의 순서를 확인하려면 findIndex
와 callback 함수
를 사용하면 된다. callback함수
의 결과가 true
를 반환하는 로직을 짤 수 있다.
console.log(arr.findIndex((obj) => {
obj.color === "green"
}));
// output : 3
findIndex
도 마찬가지로 요소가 없다면 -1
을 반환한다.
일치하는 요소가 2개 이상인 경우, 가장 먼저만난 요소를 반환
배열을 순서대로 순회하기 때문이다.
그렇다면 직접적으로 객체 요소에 접근하고 싶다면 어떻게 해야하는가?
const arr = [
{color : "red"},
{color : "black"},
{color : "blue"},
{color : "green"}
];
let number = 3;
console.log(
arr[
arr.findIndex((elm) => {
return elm.color === "blue";
})
]
);
조금 복잡하다면, 내부의 값을 상수로 변환해주면 된다.
const idx = arr.findIndex((elm) => {
return elm.color === "blue";
});
console.log(idx); // 2
console.log(arr.[idx]); // {color: 'blue'}
하지만, findIndex
도 괜찮지만,
배열의 요소에 직접 접근하는 방법이 있다. find
이다.
find
는 인덱스를 가져오는 게 아니라 조건에 부합하는 요소를 그대로 가지고 온다.
const element = arr.find((elm) => {
return arr.color === "blue";
});
console.log(element); // {color:"blue"}
findIndex
와 find
는 전달하는 콜백함수의 기능은 같다.
(조건을 만족하는 첫 번째 요소를 반환함).
find
는 만족하는 요소 자체를 반환
findIndex
는 요소의 인덱스를 반환
const arr = [
{num:1, color : "red"},
{num:2, color : "black"},
{num:3, color : "blue"},
{num:4, color : "green"},
{num:5, color : "blue"}
];
color가 blue인 것만 필터링 하고 싶다면 어떻게 해야할까?
내장함수 filter
를 사용하면 된다.
console.log(arr.filter((elm) => elm.color === "blue"));
// (2) [Object, Object]
조건을 만족하는 요소를 배열로 반환받으려면 filter
를 쓰자.
배열을 원하는 인덱스만큼 자르고 싶다면? slice
를 쓰자.
console.log(arr.slice(begin, end));
여기서 begin, end에 0,2를 넣어보자
console.log(arr.slice(0, 2));
//(2) [Object, Object]
하지만, end부분에 2를 넣으먄 인덱스 1까지 짜른다.
end -1 이라고 생각하면 된다.
slice()
는 원본 배열을 변화시키고
filter()
와 map()
은 새로운 배열을 반환한다.
이제 잘라봤으니, 다시 붙여보자.
다시 붙이기 위해선, concat()
을 쓰면 된다.
const arr1 = [
{num:1, color : "red"},
{num:2, color : "black"},
{num:3, color : "blue"}
];
const arr2 = [
{num:4, color : "green"},
{num:5, color : "blue"}
];
console.log(arr1.concat(arr2));
// (5) [Object, Object, Object, Object, Object]
자르는 것과 붙이는 걸 했으니, 이제 정렬을 해보자.
let chars = ["나", "다", "가"];
console.log(chars);
// (3) ['나', '다', '가']
여기서 문자열을 사전식으로 정렬하고 싶다면 sort()
를 쓰면된다.
let chars = ["나", "다", "가"];
chars.sort();
console.log(chars);
// (3) ['가', '나', '다']
sort()
는 정렬된 배열을 반환하는 게 아니라 원본 배열의 순서를 정렬한다.
이번엔 문자열이 아닌 숫자를 넣어보자.
let numbers = [0,1,3,2,10,30,20];
console.log(numbers);
// (7) [0, 1, 10, 2, 20, 3, 30]
sort()
는 숫자가 아닌 문자를 기준으로 정렬한다. (사전순)
그렇기 때문에 sort 메서드에 전달할 비교함수를 만들어 주어야 한다.
const compare = (a,b) => {
//1. 같다
//2. 크다
//3. 작다
if (a > b) {
// 크다
return 1;
}
if (a < b) {
//작다
return -1;
}
// 같다
return 0;
};
numbers.sort(compare);
console.log(numbers);
// (7) [0, 1, 2, 3, 10, 20, 30]
비교함수를 넣으니 정상적으로 출력되는 것을 알 수 있다.
위의 비교함수를 정확히 이해해보자.
비교함수는 3가지로 비교하고 결과를 내 놓는다.
예를 들어 a = 1, b = 2를 넣는다고 생각해보면,
const compare = (1,2) => {
if (1 > 2) {
return 1; // a가 b보다 뒤에 있어야 한다는 뜻, 큰 값이 뒤로
}
if (1 < 2) {
return -1; // b가 a보다 앞에 있어야 한다는 뜻, 작은 값이 앞으로 가야 한다는 뜻
}
return 0;
};
음수가 나오면 a가 앞으로, 양수가 나오면 a가 뒤로, 같을 땐 자리를 바꾸지 않는다면 배열의 순서가 오름차순으로 정리가 된다.
만약 내림차순으로 바꾸고 싶다면 비교함수의 return 값
을
-1 -> 1
, 1 -> -1
로 바꾸어 주면 된다.
그래서 이렇게 비교함수를 만들어 sort
메소드에 전달을 한다면,
정수 배열뿐만 아니라, 객체 배열, 배열의 배열, 함수의 배열 또한 원하는대로 정렬할 수 있다.
마지막으로, 모든 문자열들을 합치는 메소드를 알아보자.
const. arr = ["Hi", "bradley", "Good to see you", "again"];
console.log(arr[0], arr[1], arr[2], arr[3]);
// Hi bradley Good to see you again
이 방식은 너무 하드한 방법이다. join()
을 쓰자.
const. arr = ["Hi", "bradley", "Good to see you", "again"];
console.log(arr.join());
// Hi,bradley,Good to see you,again
그런데 쉼표로 구분되어 나타난다. 쉼표를 없애려면 공백을 넣어준다.
console.log(arr.join(""));
// Hi bradley Good to see you again
그 말은 즉슨, join안에 들어가는 값은 구분자가 되는 것이다.
console.log(arr.join("-"));
// Hi-bradley-Good to see you-again
**shift() : 배열 첫번째 요소 삭제, 결괏값으로 삭제된 원소 반환**
const arr = [1,2];
console.log(arr.shift()); // 1
console.log(arr) // [2]
**unshift() : 배열 첫 번째 인덱스에 원소 추가, 결괏값으로 배열의 새로운 길이 반환**
const arr = [1,2];
console.log(arr.unshift(-1,0)); // 4
console.log(arr); // [-1, 0, 1, 2]
**push() : 배열 마지막 인덱스에 하나 이상의 원소 추가, 결괏값으로 배열의 새로운 길이 반환**
const arr = [1];
console.log(arr.push(2,3)); // 3
console.log(arr); // [1,2,3]
**pop() : 배열 마지막 인덱스에 해당 원소 삭제, 그 값을 결과값으로 반환**
const arr = [1,2];
console.log(arr.pop()); // 2
console.log(arr); // [1]
**splice(a,b,c) : 배열 원소 추가, 교체 또는 삭제해 배열 데이터를 변경
결괏값으로 삭제된 원소 배열 반환 (a:index, b:지울갯수, c:추가요소)**
const arr = [1,2,3];
console.log(arr.splice(1,2, 'a')); // [2,3]
console.log(arr); //[1, a]
arr.**sort(compareFunction) : 정렬 순서를 정의하는 비교 함수를 사용해 정렬.
비교 함수 생략 시, 문자 유니코드 포인트값 따름.**
const arr = [3,2,4,21,55];
arr.sort();
console.log(arr); // [2, 21, 3, 4, 55]
오름차순 : [1,2,3].sort((a,b) => {a-b}); // [1,2,3]
내림차순 : [1,2,3].sort((a,b) => {b-a}); // [3,2,1]
**concat() : 인자로 넘긴 배열 또는 값들을 기존 배열에 합쳐 새로운 배열 생성 반환**
const arr = [1,2,3];
const newArr = arr.concat([4,5]);
console.log(arr); // [1,2,3]
console.log(newArr); // [1,2,3,4,5]
**arr.slice(begin,end) : 배열에서 특정 범위의 원소를 복사해 새로운 배열을 생성 반환.
(단, 얕은 복사를 수행 -> 배열 원소가 객체면 참조 유지)**
const obj = {};
const arr = [1, obj, 3];
const newArr = arr.slice(1,2);
// slice() 메서드는 얕은 복사를 하기 때문에 배열 내에 중첩된 객체의 참조가 유지됨.
console.log(newArr[0] === obj); // true
* 배열 복사 하는 또 다른 방법 -> 전개 연산자 사용 (Spread Operator)
- slice() 메서드와 마찬가지로 얕은 복사 수행
const arr = [1,2,3];
const newArr = [...arr];
console.log(newArr); // [1,2,3];
**map() : 배열의 모든 원소를 인자로 받은 함수를 실행, 특정한 형식으로 변경,
변경한 원소들로 새로운 배열을 생성해 반환**
const arr = [1,2,3];
const newArr = arr.map(x => x+1);
console.log(newArr); // [2,3,4]
**forEach() : 인자로 받은 함수를 배열의 모든 원소를 대상으로 실행, undefined 반환**
const arr = [1,2,3];
const newArr = arr.forEach(x => console.log(x)); // 1, 2, 3
****
**filter() : 인자로 받은 함수의 테스트를 통과하는 원소들로 새로운 배열을 생성해 반환**
const arr = [1,2,3];
const newArr = arr.filter(x => x !== 1);
console.log(newArr); // [2,3]