Ayden's journal

배열의 메소드

값 변경 : with()

with()은 할당 연산자 없이 특정 인덱스의 값을 바꾸며, 값이 바뀐 새로운 배열을 반환한다. 기존의 배열은 수정되지 않는다. 이를 통해 조작을 수행하는 동안 메소드 체이닝을 사용할 수 있다.

// 할당 연산자를 사용했을 때
const arr = [1, 2, 3]
const newArr = [...arr]
newArr[0] = 12
newArr.forEach(() => {})
// with()을 사용했을 때
const arr = [1, 2, 3]
arr.with(0, 12).forEach(() => {})

 

 

스택과 큐 : shift∙unshift()와 push∙pop()

알고리즘을 풀다보면 배열을 사용해서 스택과 큐를 구현하는데, 이 네 가지 메소드를 사용해 FIFO와 LIFO를 구현한다. 특히 배열의 맨 앞과 뒤를 삭제하는 메소드의 경우 삭제한 item을 반환한다는 점을 유용하게 써먹을 수 있다.

// 배열의 새로운 길이 반환
arr.unshift('newValue1', 'newValue2'); // 배열의 맨 앞에 하나 이상의 요소를 추가
arr.push('newValue'); // 배열의 끝에 하나 이상의 요소를 추가
// 삭제된 item을 반환
arr.shift() // 배열의 첫 요소를 삭제
arr.pop() // 배열의 마지막 요소를 삭제

 

 

요소 조작 : splice()와 slice()

splice()는 배열의 특정 인덱스로부터 아이템을 제외하고, 선택적으로 그 자리에 특정 아이템을 추가할 수 있는 메소드이다. splice()는 삭제한 아이템으로 이루어진 배열을 반환하며, arr.splice(0, 0)과 같이 0개의 아이템을 삭제하는 경우 빈 배열을 반환한다.

// i번 인덱스로부터 끝까지 삭제
arr.splice(i)
// i번 인덱스로부터 n개의 아이템 삭제
arr.splice(i, n)
// i번 인덱스로부터 n개의 아이템을 삭제하고
// i번 인덱스 자리에 아이템 추가
arr.splice(i, n, ...list)

 

slice()는 어떤 배열의 특정 부분을 새로운 배열로 반환하지만, 원본 배열은 바뀌지 않는다. splice처럼 두 번째 인자를 제공하지 않는 경우 배열의 마지막까지 추출하지만, 추출할 아이템의 개수를 의미하는 splice와 달리 slice의 두 번째 인자는 추출을 종료할 기준 인덱스를 의미한다. slice가 반환하는 배열에 추출 종료 인덱스는 포함되지 않는다는 점을 기억해야 한다.

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// Expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// Expected output: Array ["bison", "camel", "duck", "elephant"]
console.log(animals.slice(-2));
// Expected output: Array ["duck", "elephant"]
console.log(animals.slice(2, -1));
// Expected output: Array ["camel", "duck"]

 

 

 

반복 작업 : forEach()와 map()

둘 다 배열의 요소를 하나씩 확인하면서 반복 작업을 진행하는 반복문이다. 그러나 배열을 돌기만 할 뿐인 forEach()와 달리 map()은 새로운 배열을 반환한다.

const numbers = [1, 2, 3];
numbers.forEach((element, index, array) => {
console.log(`${element}, ${index}`);
})
const firstNames = ['진환', '서연', '주성'];
const lastNames = ['김', '이', '박'];
const getFullNames = firstNames.map((element, index, array) => {
return lastNames[index] + firstNames[index];
});
console.log(getFullNames); // (3) ["김진환", "이서연", "박주성"]

 

 

조건 탐색 : filter()와 find∙findLast()

filter() 불린을 리턴하는 콜백 함수를 사용하여, 조건을 만족하는 요소로 이루어진 새로운 배열을 반환한다.

const serverNameLolTierList = [
{name: '글쟁', tier: 'bronze', team: 'red'},
{name: '골드', tier: 'gold', team: 'blue'},
{name: '레빗', tier: 'silver', team: 'blue'},
{name: '루챠', tier: 'bronze', team: 'blue'},
{name: '프롬', tier: 'gold', team: 'red'},
{name: '경식', tier: 'bronze', team: 'red'},
];
const blue = serverNameLolTierList.filter((el, i, arr) => {
return el.team === 'blue'; // 이 조건이 참일 때의 el을 모아서 새로운 객체로 반환
});
console.log(blue); // (3) [{name: '골드', tier: 'gold', team: 'blue'}, {name: '레빗', tier: 'silver', team: 'blue'}, {name: '루챠', tier: 'bronze', team: 'blue'}]

반면 find()는 콜백 함수가 반환하는 조건과 일치하는 첫번째 요소를 반환하고 반복을 즉시 종료한다. findLast()는 find()와 비슷하지만 배열의 역순으로 찾기 시작한다는 점이 다르다. 

const gold = serverNameLolTierList.find((el, i, arr) => {
return el.tier === 'gold';
});
console.log(gold); // {name: '골드', tier: 'gold', team: 'blue'}

두 메소드 모두 조건에 맞는 요소가 없다면 undefined를 반환한다. 따라서 filter의 경우 반환되는 값이 언제나 Array<unknown> | undefined인 반면, find는 unknown | undefined를 반환한다.

 

 

조건 만족 : some() every()

두 메소드 모두 배열 안에 리턴 조건을 만족하는 요소가 있는지를 확인한다. 다만, some()은 조건을 만족하는 요소가 하나라도 있는지를 확인하는데, 반면에 every()는 모든 요소가 조건을 만족하는지(혹은 하나의 요소라도 조건을 만족하지 않는지)를 확인한다. 조건 만족 여부에 따라 불린값을 반환한다.

const numbers = [1, 3, 5, 7, 9];
// 5보다 큰 요소가 하나라도 있는가
const someReturn = numbers.some((el, i, arr) => el > 5;);
console.log(someReturn); // true;
// 모든 요소가 5보다 큰가
const everyReturn = numbers.every((el, i, arr) => el > 5;);
console.log(everyReturn); // false;

빈 배열을 받으면 some()은 false를, every()는 true를 리턴한다.

 

 

존재 여부 : includes()와 indexOf(), lastIndexOf()

두 메소드 모두 배열 안에 특정 item이 포함되어있는지를 확인한다. 존재 여부만 확인하고 싶다면 boolean을 반환하는 includes()를 사용하고, 위치까지 알아야 한다면 indexOf()와 lastIndexOf()를 사용한다.

const numbers = [1, 3, 5, 7, 9, 5];
numbers.includes(5) // true
numbers.indexOf(5) // 2
numbers.lastIndexOf(5) // 5

 

 

조건 만족 존재 여부 : findIndex∙ findLastIndex()

findIndex()는 마치 some()과 indexOf()를 합쳐놓은 것처럼 주어진 콜백 함수를 만족하는 배열의 첫 번째 요소에 대한 인덱스를 반환한다. 콜백 함수를 만족하는 요소가 없다면 -1을 반환한다.

const array = [5, 12, 8, 130, 44];
const number = array.findIndex(e => e > 13)
console.log(number) // 3

 

 

누적 계산 : reduce∙reduceRight()

reduce()는 누적값을 계산할 때 활용하며, 첫번째 아규먼트로는 콜백 함수를, 두번째 아규먼트로 누산기 초기값(initial accumulator value)을 활용한다. 콜백 함수의 첫번째 아규먼트로는 누산기(accumulator)라고 불리는 독특한 파라미터를 활용한다.

이 누산기에는 반복에 따른 콜백 함수의 리턴값이 누적되어 저장된다. 첫 반복에는 누산기에 저장된 값이 없으므로 누산기 초기값이 적용된다. 누산기 초기값은 생략할 수 있는데, 콜백 함수가 복잡해질 수록 결과를 예측하기 어려워지기 때문에 가급적 생략하지 않는 것이 권장된다.

const numbers = [1, 2, 3, 4]; // reduceconst
sumAll = numbers.reduce((accumulator, el, i, arr) => {
return accumulator + el;
}, 0);
console.log(sumAll); // 10

reduceRight()는 다른 모든 것은 reduce()와 동일하지만 배열의 마지막에서부터 누적값을 계산해나가며, 둘 다 반복이 끝나면 최종적으로는 누산기의 값을 반환한다.

 

 

순서 변경 : sort∙toSorted()와 reverse∙ toReversed

둘 다 배열의 순서를 조작하는 메소드이다. 단순히 sort()만 사용하면 유니코드 문자열에 따라 배열을 정렬하기 때문에 숫자형으로 이루어진 배열은 원하는 순서로 정렬되지 않는다. 때문에 콜백 함수를 사용하여 순서를 따로 정해주어야 한다. 반면에 reverse()는 단순히 배열의 순서를 뒤집기만 할 뿐이다.

const letters = ['D', 'C', 'E', 'B', 'A'];
letters.sort();
console.log(letters); // (5) ["A", "B", "C", "D", "E"]
const numbers = [1, 10, 4, 21, 36000];
// 오름차순 정렬
numbers.sort((a, b) => a - b);console.log(numbers); // (5) [1, 4, 10, 21, 36000]
// 내림차순 정렬
numbers.sort((a, b) => b - a);console.log(numbers); // (5) [36000, 21, 10, 4, 1]
const letters = ['D', 'C', 'E', 'B', 'A'];
letters.reverse();
console.log(letters); // (5) ["A", "B", "E", "C", "D"]

두 메소드 모두 메소드를 실행하는 원본 배열의 요소들을 정렬한다. 때문에 한 번 정렬하면 그 전의 순서로 되돌릴 수 없다. 따라서 원본 배열은 건드리지 않으면서도 특정한 순서로 정렬된 배열이 필요하다면 toSorted()와 toReversed()를 사용해야한다. 이 메소드들은 기능적으로 sort() ∙ reverse()와 같되 원본 배열은 건드리지 않고 순서를 변경하여 새로운 배열로 반환한다는 차이가 있다.

 

 

자르고 붙이기 : split()과 join()

이 두 메소드는 각각 문자열을 배열로, 배열을 문자열로 바꾸어 반환한다. 이 두 메소드를 필요할 때 각각 사용할 수도 있지만, 함께 사용할 경우 조건에 맞는 문자를 없애고, 그 자리에 원하는 문자를 넣는 식으로 사용할 수 있다.

function solution(s) {
let numbers = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
let answer = s;
for(let i=0; i < numbers.length; i++) {
answer = answer.split(numbers[i]).join(i);
}
return Number(answer);
}
블로그의 프로필 사진

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기