12/26/2023

Array

slice()

slice() 메서드는 문자열에서 사용할 수 있는 slice() 메서드와 매우 유사하다. slice() 메서드는 배열의 일부를 추출하며 원본 배열을 변경하지 않고 새로운 배열을 반환한다. 문자열과 마찬가지로 추출을 시작할 시작 인덱스와 추출이 끝나는 끝 인덱스가 존재하며 끝 인덱스는 추출에 포함되지 않는다. 추출된 배열의 길이는 두 인덱스의 차이와 같다. 문자열에서와 마찬가지로 음수 시작 인덱스를 정의할 수 있고 배열의 끝부터 추출을 시작한다. -1은 항상 어떤 배열이든 마지막 요소이다. 마지막으로, slice 메소드를 사용하여 배열의 얕은 복사를 수행할 수 있다. 이는 전개 연산자와 정확히 같은 작업을 수행한다. slice() 메서드가 정말 필요한 경우는 여러 메소드를 연결해서 호출하고 싶을 때이다.
1
2
3
4
5
6
7
8
9
const arr = [1234];
 
console.log(arr.slice(1)); // 인덱스 1부터 배열의 끝까지 추출한다. [ 2, 3, 4 ]
console.log(arr.slice(13)); // 인덱스 1부터 인덱스 2까지 추출한다. [ 2, 3 ]
console.log(arr.slice(-2)); // 인덱스 -2부터 배열의 끝까지 추출한다. [ 3, 4 ]
console.log(arr.slice(-1)); // 배열의 끝을 추출한다. [ 4 ]
console.log(arr.slice(1-2)); // 인덱스 1부터 인덱스 -2까지 추출한다. [ 2 ]
console.log(arr.slice()); // 배열 전체를 추출한다(얕은 복사). [ 1, 2, 3, 4]
console.log([...arr]); // slice()와 완전히 동일한 작업을 수행하는 전개 연산자 [ 1, 2 ,3, 4 ]
cs


splice()

splice() 메서드는 slice() 메서드와 거의 동일한 방식으로 작동하지만 가장 큰 차이점은 원본 배열을 변경한다는 것이다. splice() 메서드는 원본 배열을 변경시키므로 배열의 일부를 취해서 반환하고 그리고 원래 배열 자체가 그 추출된 부분을 잃는다. 일반적으로 splice() 메서드를 사용하여 배열에서 하나 이상의 요소를 삭제한다. 매우 흔한 사용 사례는 배열에서 마지막 요소를 간단히 제거하는 것이다. 1번째 매개변수는 slice() 메서드와 동일하게 작동하지만 2번째 매개변수는 삭제하려는 요소의 개수이다.
1
2
3
4
5
const arr = [12345];
 
arr.splice(-1); // 배열의 마지막 요소를 제거한다. [ 1, 2, 3, 4 ]
arr.splice(12); // 인덱스 1번부터 시작해서 2개의 요소를 제거한다. [ 1, 4 ]
console.log(arr);
cs


reverse() & concat() & join()

reverse() 메서드는 원본 배열을 변경해서 역순 배열을 반환한다. concat() 메서드는 두 개의 배열을 연결하며 모든 원본 배열은 그대로 유지된다. join() 메서드는 구분자로 배열의 요소를 결합한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// reverse()
const arr = [12345];
console.log(arr.reverse()); // [ 5, 4, 3, 2, 1 ]
console.log(arr); // [ 5, 4, 3, 2, 1 ]
 
// concat()
const word1 = ["i""c""e"];
const word2 = ["c""r""e""a""m"];
 
const word = word1.concat(word2);
console.log(word); // [ "i", "c", "e", "c", "r", "e", "a", "m" ]
console.log([...word1, ...word2]); // word1.concat(word2)와 동일한 작업을 수행한다.
 
// join()
console.log(word1.join(".")); // i.c.e
cs


at()

at() 메서드는 ES2022에 새로 도입된 배열 메서드로 인덱스 위치의 값을 가져온다. 즉, 기존의 대괄호 표기법([])을 at() 메서드로 바꿀 수 있다. 메서드 자체는 그렇게 유용해 보이진 않을 수도 있는데 at() 메서드는 대괄호 표기법에는 존재하지 않는 특별한 기능이 있다. 배열의 마지막 요소를 가져오고 싶은데 배열의 길이를 모르는 상황이라면 [배열의 길이 - 1]으로 마지막 요소를 구한다. 다른 방법은 바로 이전에 배운 slice 메서드를 사용하는 것으로 원본 배열의 복사본에서 -1을 사용해 배열의 마지막 요소를 가져올 수 있다. 배열의 마지막 요소만 있는 배열의 복사본에서 첫 번째 값을 꺼내야 하기 때문에 [0]을 사용한다. at() 메서드는 이 과정을 더 쉽게 만든다. slice() 메서드와 같이 음수 인덱스를 사용한다. at() 메서드를 사용할 지 아니면 대괄호 표기법을 사용할 지는 상황에 따라 다르다. 배열의 마지막 요소에 도달하려거나 기본적으로 배열의 끝에서부터 세고 싶다면 at() 메서드를 사용하는 게 좋다. 또한, 메서드 체이닝(여러 메서드를 한번에 모두 결합한다.)이라 불리는 것을 하고 싶으면 at() 메서드가 적합하다. 하지만 단순히 배열에서 값을 빠르게 가져오고 싶다면 대괄호 표기법을 계속 사용할 수 있다. at() 메서드를 문자열에 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
const fruits = ["사과""수박""키위""배"];
console.log(fruits[1]); // 수박
console.log(fruits.at(1)); // 수박
 
console.log(fruits[fruits.length - 1]); // 배
console.log(fruits.slice(-1)[0]); // 배
 
console.log(fruits.at(-1)); // 배
 
console.log("지코바치킨".at(2)); // 바
cs


forEach()

배열을 순회하는 forEach() 메서드는 콜백 함수가 필요하다. 즉, forEach는 고차 함수이다. forEach() 메서드는 배열을 순회하면서 각 요소마다 콜백 함수를 실행한다. forEach() 메서드가 콜백 함수를 호출할 때 각 요소마다 현재 배열 요소를 인자로 전달한다. forEach() 메서드가 콜백 함수를 호출할 때 배열의 현재 배열 요소를 전달하는 것 뿐만 아니라 인덱스 및 배열 자체를 전달할 수 있다. 첫 번째 매개변수는 현재 요소이고 두 번째 매개변수는 인덱스, 세 번째 매개변수는 배열이다. 이는 인덱스가 먼저오는 for...of의 entries() 메서드와 다르다. forEach() 메서드와 for...of의 가장 근본적인 차이점은 forEach() 메서드의 경우 break를 사용하여 루프를 탈출할 수 없다. 즉, continue와 break 문은 forEach() 메서드에서 전혀 작동하지 않는다. 따라서, forEach() 메서드는 항상 배열 전체를 순회한다.
1
2
3
4
5
6
7
8
9
const prices = [27000-3000-5000-4000012000050000-90000];
 
prices.forEach(function (price, index, array) {
  if (price > 0) {
    console.log(`${index + 1}일: 주가가 ${price}원 상승했습니다.`);
  } else {
    console.log(`${index + 1}일: 주가가 ${price}원 하락했습니다.`);
  }
});
cs

forEach() 메서드는 맵(map)과 세트(set)에서도 사용할 수 있다. 밑의 코드를 보면, 배열의 배열에서 각각의 배열 요소는 내부 배열의 맵의 하나의 항목이다. 콜백 함수도 세 개의 매개변수를 가지고 있는데 forEach() 메서드가 호출될 때 콜백 함수는 세 개의 인자와 함께 호출된다. 첫 번째는 현재 값이고 두 번째는 키이며, 세 번째는 순회되고 있는 맵 자체이다. 유일한 값을 가지는 세트의 forEach() 메서드의 콜백 함수는 맵과 마찬가지로 3개의 매개변수를 가진다. 키와 값이 정확히 같은데 세트는 키와 인덱스가 없기 때문이다. 키가 아무 의미도 없기에 두 번째 매개변수의 이름에 밑줄을 사용해서 필요하지 않은 변수라고 명시할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const movies = new Map([
  ["Sports""Moneyball"],
  ["Businesss""The Big Short"],
  ["Sc-fi""The Matrix"],
]);
 
movies.forEach(function (movie, key, map) {
  console.log(`${key}: ${movie}`);
});
 
const words = new Set(["나무""숲""바다""강""호수""산""산""바다"]);
 
words.forEach(function (value, _, set) {
  console.log(`${value}`);
});
cs


map()

map() 메서드는 배열을 순회하는데 forEach() 메서드와 달리 새로운 배열을 반환한다. 새로운 배열은 각 위치에 원래 배열 요소에 콜백 함수를 적용한 결과를 갖고있다. 콜백 함수도 현재 배열 요소를 받으며 새로운 배열에 현재 위치에 들어갈 값을 반환한다. forEach() 메서드처럼 map() 메서드도 동일한 세 가지 매개변수에 접근할 수 있다. 현재 배열 요소 이외에 현재 인덱스와 배열 자체에 접근할 수 있다. forEach() 메서드는 부작용을 만들지만 map() 메서드에서는 각 반복에서 부작용을 만들지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const kiloToPoundRatio = 2.20462;
const kilos = [211007752848043];
 
const pounds = kilos.map(function (kilo) {
  return kilo * kiloToPoundRatio;
});
 
console.log(kilos);
console.log(pounds);
 
const prices = [27000-3000-5000-4000012000050000-90000];
 
const fluctuations = prices.map((price, index, array) => {
  return `${index + 1}일: 주가가 ${
    price > 0 ? `${price}원 상승했습니다.` : `${-price}원 하락했습니다.`
  }`;
});
 
console.log(fluctuations);
cs


filter()

filter() 메서드는 특정 조건을 만족하는 요소를 여과하는 데 사용된다. 조건은 콜백 함수로 지정한다. map() 메서드나 forEach() 메서드와 마찬가지로, 현재 배열 요소와 인덱스 그리고 배열 자체에 접근할 수 있다.
1
2
3
4
5
6
7
const prices = [27000-3000-5000-4000012000050000-90000];
 
const gains = prices.filter((price, index, array) => {
  return price > 0;
});
 
console.log(gains);
cs


reduce()

reduce() 메서드는 배열의 모든 요소를 하나의 값으로 축약한다. reduce() 메서드도 콜백 함수를 받지만 map() 메서드나 forEach() 메서드와 다르다. 첫 번째 매개변수는 누산기(accumulator)로 반환하고자 하는 값을 계속해서 축적한다. 콜백 함수는 배열을 순환하면서 매번 호출되는데 reduce() 메서드도 배열을 순환하고 각 반복에서 이 콜백을 호출하며 누산기는 각 반복에서 이전 모든 값들의 현재 합이다. 나머지 매개변수는 현재 배열 요소, 인덱스 그리고 배열 자체이다. 콜백 함수는 reduce() 메서드의 첫 번째 매개변수인데 reduce() 메서드는 두 번째 매개변수를 가진다. 즉, 누산기의 초기값으로 이 값은 첫 번째 반복에서의 누산기의 초기값이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const prices = [27000-3000-5000-4000012000050000-90000];
 
const total = prices.reduce((total, price, index, array) => {
  console.log(`${index}번째 합: ${total}`);
  return total + price;
}, 0);
 
console.log(total);
 
const biggestGain = prices.reduce((biggestGain, price) => {
  if (biggestGain > price) {
    return biggestGain;
  } else {
    return price;
  }
}, prices[0]);
 
console.log(biggestGain);
cs


find()

find() 메서드로 조건에 따라 배열의 요소 하나를 가져온다. 앞서 언급한 메서드들처럼 find() 메서드도 조건과 콜백 함수를 받는다. find() 메서드는 filter() 메서드와 비슷하지만 두 가지 근본적인 차이가 있다. 첫째, filter() 메서드는 조건과 일치하는 모든 요소를 반환하는 반면 find() 메서드는 첫 번째 일치하는 요소만을 반환한다. 더 중요한 점은, filter() 메서드는 새로운 배열을 반환하는 반면에 find()는 배열이 아니라 요소 자체만을 반환한다.


findIndex()

findIndex() 메서드는 find() 메서드와 거의 비슷하게 작동하지만 이름에서 알 수 있듯이 findIndex() 메서드는 찾은 요소의 인덱스를 반환하고 요소 자체를 반환하지 않는다. 또한 다른 메서드처럼 콜백 함수를 사용하는데 매우 유사한 콜백 함수를 가진다. 콜백 함수에 true 또는 false를 반환할 조건을 전달하고 그리고 findIndex 메서드는 조건과 일치하는 배열의 첫 번째 요소의 인덱스를 반환한다. 즉, 조건이 true를 반환하는 경우의 인덱스를 반환한다. find() 메서드와 findIndex() 메서드 모두 현재 인덱스와 배열 자체에도 접근할 수 있다. 현재 요소 외에도 이 두 가지 다른 값도 사용할 수 있다. find() 메서드와 findIndex() 메서드는 ES6에서 JavaScript에 추가되었다. 따라서 이전 버전의 브라우저에서는 작동하지 않을 수 있다. findIndex() 메서드와 indexOf() 메서드의 큰 차이점은 indexOf() 메서드는 배열 안에 있는 값만을 찾을 수 있다. 그래서, 배열에 값이 포함되어 있다면 true이고 아니면 false다. 그러나 반면에 findIndex() 메서드에서는 복잡한 조건을 만들 수 있다. 둘 다 인덱스를 반환하지만 findIndex() 메서드가 훨씬 간단하다.


some() & every()

includes() 메서드와 some() 메서드는 유사하지만 includes() 메서드는 동등성(===)만 확인한다. 반면에 some() 메서드에서 조건을 지정할 수 있다. 조건이 true인 값이 하나라도 있는 경우 some 메서드()는 true를 반환한다. every() 메서드는 some() 메서드와 꽤 유사하지만 두 메서드의 차이점은 every() 메서드는 배열의 모든 요소가 조건을 만족할 때만 true를 반환한다. 즉, 모든 요소가 콜백 함수의 테스트를 통과하는 경우에만 every() 메서드가 true를 반환한다. 지금까지 콜백 함수를 항상 배열 메서드의 인수로 직접 작성했는데 콜백 함수를 따로 작성한 다음 전달할 수 있다. 따라서, 모든 배열 메서드에 콜백 함수를 직접 쓸 이유가 없다. 다양한 메서드에 대한 콜백이 필요한 경우에도 마찬가지이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const prices = [27000-3000-5000-4000012000050000-90000];
 
// 동등성.
console.log(prices.includes(-5000)); // true
 
// 조건.
const anyLoss = prices.some((price) => {
  return price < 0;
});
console.log(anyLoss); // true
 
const allGains = prices.every((price) => {
  return price > 0;
});
console.log(allGains); // false
 
// 콜백 함수.
const loss = (price) => {
  return price < 0;
};
 
console.log(prices.some(loss)); // true
console.log(prices.every(loss)); // false
console.log(prices.filter(loss)); // [ -3000, -5000, -40000, -90000 ]
cs


flat() & flatMap()

ES2019에 소개된 flat() 메서드 콜백 함수를 받지 않으면 중첩된 배열을 제거하고 배열을 평평하게 만든다. 인자가 없으면 flat() 메서드가 배열을 평평하게 만들 때 오직 1단계 깊이만 들어간다. '깊이' 인자를 사용하여 이를 수정할 수 있는데 코드에서 보이는 것처럼 2를 입력하면 이것은 이제 두 번째 중첩 수준까지 평평하게 만든다. ES2019에 도입된 flatMap() 메서드는 map() 메서드와 flat() 메서드를 결합하여 하나의 메서드로 만든 것으로 성능이 더 좋다. flatMap() 메서드는 map() 메서드와 정확히 동일한 콜백 함수를 받으며 배열을 평평하게 만드는 메서드이다. 다만 flatMap() 메서드는 오직 1단계 깊이만 들어가기 때문에 를 변경할 수는 없다. 따라서 하나 이상의 단계로 깊이 들어가야 할 경우에는 여전히 flat() 메서드를 사용해야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const nums1 = [[425], 7342, [59223], 82, [10], 3];
 
console.log(nums1.flat()); // [ 42, 5, 7342, 59, 223, 82, 1, 0, 3 ]
 
const nums2 = [[425], 7342, [59, [223965]], 82, [1, [0]], 3];
 
console.log(nums2.flat()); // [ 42, 5, 7342, 59, [ 223, 965 ], 82, 1, [ 0 ], 3 ]
console.log(nums2.flat(2)); // [ 42, 5, 7342, 59, 223, 965, 82, 1, 0, 3 ]
 
const trading1 = {
  date: "2021-03-31",
  performances: [120-800350-200100],
};
 
const trading2 = {
  date: "2021-06-30",
  performances: [-500180-300250700],
};
 
const trading3 = {
  date: "2021-09-30",
  performances: [150-220800-130270],
};
 
const trading4 = {
  date: "2021-12-31",
  performances: [-170300-250190-600],
};
 
const tradings = [trading1, trading2, trading3, trading4];
 
// flat
const netPerformance1 = tradings
  .map((trading) => trading.performances)
  .flat()
  .reduce((total, performance) => total + performance, 0);
 
console.log(netPerformance1); // 240
 
// flatMap
const netPerformance2 = tradings
  .flatMap((trading) => trading.performances)
  .reduce((total, performance) => total + performance, 0);
 
console.log(netPerformance2); // 240
cs


sort()

sort() 메서드는 배열을 알파벳순으로 정렬한다. 원본 배열을 변형시키기 때문에 사용할 때 매우 주의해야 한다. 문자열과 달리 숫자에 메서드를 적용하면 이상한 결과가 나오는데 sort() 메서드가 문자열을 기반으로 정렬하기 때문이다. 즉, 모든 것을 문자열로 변환한 다음 정렬을 수행한다. 따라서 숫자대로 정렬하려면 콜백 함수를 전달한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 문자열
const movies = [
  "Tenet",
  "Fight Club",
  "Drive",
  "Blade Runner 2049",
  "The Matrix",
  "Close Encounters of the Third Kind",
  "The Big Short",
  "2001: A Space Odyssey",
];
console.log(movies.sort()); // [ '2001: A Space Odyssey', 'Blade Runner 2049', 'Close Encounters of the Third Kind', 'Drive', 'Fight Club', 'Tenet', 'The Big Short', 'The Matrix' ]
 
// 숫자
const prices = [27000-3000-5000-4000012000050000-90000];
console.log(prices.sort()); // [ -3000, -40000, -5000, -90000, 120000, 27000, 50000 ]
 
// 음수 반환: A, B (순서 유지)
// 양수 반환: B, A (순서 변경)
 
// 오름차순
prices.sort((a, b) => a - b);
console.log(prices); // [ -90000, -40000, -5000, -3000, 27000, 50000, 120000 ]
 
// 내림차순
prices.sort((a, b) => b - a);
console.log(prices); // [ 120000, 50000, 27000, -3000, -5000, -400000, -90000 ]
cs


Array() & fill() & Array.from()

배열을 생성하고 채우는 방법은 다양하다. []에 요소를 직접 쓰는 방법 외에도 Array() 생성자 함수에 요소를 전달하여 배열을 만들 수 있다. 수동으로 모든 요소를 정의하지 않고 배열을 생성할 수도 있는데 가장 쉬운 방법은 Array() 생성자 함수에 하나의 인자만 전달하면 인자 길이만큼의 빈 배열이 생성된다. 빈 배열에 적용할 수 있는 한 가지 메서드가 있는데 바로 fill() 메서드이다. 인자를 전달하면 배열 전체를 이 인자로 채운다. 즉, 원본 배열을 변형한다. fill() 메서드는 slice() 메서드와 비슷한데 배열을 채우려는 값 외에도 시작 인덱스와 끝 인덱스를 지정할 수 있다. 끝 인덱스는 배열에 포함되지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const arr1 = [12345];
const arr2 = new Array(12345);
 
// 빈 배열 & fill() 메서드
const arr3 = new Array(5);
console.log(arr3); // [ <5 empty items> ]
 
arr3.fill(1); // 배열 전체를 1로 채운다.
console.log(arr3); // [ 1, 1, 1, 1, 1 ]
 
arr3.fill(324); // 인덱스 2부터 인덱스 3(4 - 1)까지 배열을 3으로 채운다.
console.log(arr3); // [ 1, 1, 3, 3, 1 ]
 
// Array.from
const arr4 = Array.from({ length5 }, () => 1);
console.log(arr4); // [ 1, 1, 1, 1, 1 ]
 
const arr5 = Array.from({ length5 }, (_, index) => index + 1);
console.log(arr5); // [ 1, 2, 3, 4, 5 ]
cs

arr1 배열을 프로그래밍적으로 생성하려면 Array.from() 함수를 사용한다. 배열의 메서드로 from을 사용하는 것이 아니라 Array() 생성자 함수에 사용하고 있다. 여기서 Array는 함수이고 이 함수 객체에 from() 메서드를 호출한다. 1번째 인자는 length 속성으로 배열의 길이를 설정하고 2번째 인자는 매핑 함수로  map() 메서드에 전달하는 콜백 함수와 정확히 같다. 콜백 함수는 현재 요소, 현재 인덱스에 접근할 수 있다.

update: 2024.01.09

댓글 없음:

댓글 쓰기