문제 설명
정수 리스트 num_list와 정수 n이 주어질 때, num_list를 n 번째 원소 이후의 원소들과 n 번째까지의 원소들로 나눠 n 번째 원소 이후의 원소들을 n 번째까지의 원소들 앞에 붙인 리스트를 return하도록 solution 함수를 완성해주세요.
🙋♀️ 내 생각
배열의 앞에서부터 n개를 잘라서 배열의 맨 뒤에 붙이는 문제이다.
배열의 인덱스를 이용해서 범위를 지정해야겠다고 생각했고,
또 배열을 잘라야하기때문에 slice()를 써야겠다고 생각했다.
(slice()가 범위를 지정하면서 자르는 기능을 하기때문!!)
✅ 내 코드
function solution(num_list,n) {
let front_list= num_list.slice(0,n)
let back_list= num_list.slice(n,num_list.length)
return [...back_list,...front_list]
}
먼저, 잘라진 앞부분을 front_list라는 변수로 이름을 지어주고, 값을 담아주었다.
값은 num_list의 앞부분으로 slice()를 통해서 범위를 지정했다.
맨처음의 0번째 인덱스부터 시작해서, 마지막은 n-1번째 인덱스로 끝난다.
(slice()는 end인덱스는 포함하지 않는 특성을 가지고 있기때문에 end인덱스값을 n-1이 아니라 n으로 적는다)
이렇게 하면 num_list의 0부터 n-1까지의 n개의 값을 자를수있다.
여기까지하고 값을 확인해보면, 아래와 같이 앞부분 n개가 잘라진것을 볼 수 있다.
그런 다음, 뒷부분은 back_list라는 이름으로 지어주고 위에서와 마찬가지로 slice()를 통해 범위를 지정하고 자른다.
뒷부분은 n번째부터 시작해서 (num_list의 길이-1)번째 인덱스까지이다.
(위에 적었듯이, slice()는 end를 미포함하므로 마지막은 num.length로 적는다)
back_list도 테스트를 통해서 보면 입력값의 뒷부분만 잘라서 나오는 것을 확인할 수 있다.
마지막으로 각각 다르게 존재하는 2개의 배열을 합치기위해서 ...스프레드 연산자를 사용한다.
...스프레드연산자를 이용하여 배열안의 값들을 개별요소로 분리한다.
스프레드연산자를 많이 사용했지만 정확하게 알지 못하는 부분이 있는것같아서 이번 문제를 풀면서 자세하게 공부하였다.
🔫 ...스프레드 연산자 (Spread Operator, 전개연산자)
배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있다.
(mdn)
스프레드 연산자의 주요 사용법은 3가지이다.
1. 함수 호출 시 인수로 사용
myFunction(...iterableObj);
함수를 호출할 때 배열을 풀어서 개별 인수로 전달할 수 있다.
예시>
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
✔️ new를 통해서 생성자를 생성할때도 인자로 사용가능하다.
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
2. 배열리터럴
2.-1 배열의 합치기 / 배열 연결
두 개 이상의 배열을 합칠 때 사용할 수 있다.
[...iterableObj, '4', 'five', 6];
아래의 코드와 같이 배열의 중간에 원하는 배열을 삽입하는 것도 가능하고
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]
각각 다른 배열을 연결하는 것도 가능하다.
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2]; // arr1 은 이제 [0, 1, 2, 3, 4, 5]
2-2 배열 복사
var arr = [1, 2, 3];
var arr2 = [...arr]; // arr.slice() 와 유사
arr2.push(4);
// arr2 은 [1, 2, 3, 4] 이 됨
// arr 은 영향을 받지 않고 남아 있음
기존 배열은 영향을 받지 않고 남아있다.
⛔️ 주의할점: 다차원배열을 복사하는것은 적합하지 않다.
2-3. 배열의 중복제거
스프레드 연산자를 통해 배열을 전개한 후, Set객체를 이용해서 배열의 중복을 제거할 수 있다.
const arr = [1, 2, 2, 3, 3, 4, 5, 5];
const uniqueArr = [...new Set(arr)];
3. 객체의 속성 복사
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
위에 배열을 복사한 것과 유사하게, 객체도 복사할 수 있다.
또한 배열연결을 한것처럼 ...으로 객체도 연결하여 합칠 수 있다.
💻 다른사람 코드중에 배울 것
function solution(num_list, n) {
num_list.push(...num_list.splice(0, n));
return num_list
}
내가 slice()를 이용해서 앞부분, 뒷부분을 나눠서 이어붙인것과 다르게
splice()를 이용해서 num_list의 원본요소에서 특정부분만을 삭제하고 그 삭제한 부분을 다시 push를 통해서 배열의 마지막에 연결하는 방법으로 풀었다.
배열을 잘라내는 유사한 기능을 하지만, splice()에는 slice()와는 다른 큰 특징이 있는데 그런점을 잘 이용해서 푼것 같아서 공부해보았다.
slice()는 원본을 그래도 유지하지만, splice()는 원본을 변경하는 특징이 있다.
그래서 num_list.splice()를 하면 그 부분은 num_list에서 제거되고 대신 새로운 배열로 반환된다.
splice()에는 3개의 인자가 올 수 있는데 앞에 두개만 적으면 begin인덱스, 삭제할 개수이다.
그래서 num_lists.splice(0,n)은 "num_list의 0번째 인덱스부터 n개를 제거하고 새로운 배열을 반환하라"라는 의미이다.
위의 문제를 통해 자세하게 보면,
function solution(num_list, n) {
num_list.splice(0,n)
return num_list
}
위와 같이 splice()를 통해서 0부터 n개를 제거하고 num_list를 리턴하면 아래와 같이 n개의 요소가 제거된 결과가 나온다.
num_list를 리턴하는 것이아니라, num_list.splice(0,n)을 리턴하면,
function solution(num_list, n) {$
return num_list.splice(0,n)
}
아래와 같이 잘려나간 값들이 새로운 배열로 반환되는 것을 확인할 수 있다.
이런 splice()의 성질을 생각하면서 다시 위의 전체코드를 보면 쉽게 이해할 수 있다.
function solution(num_list, n) {
num_list.push(...num_list.splice(0, n));
return num_list
}
num_list의 0번째 인덱스부터 n개를 잘라서 새로운 배열에 담고 ...스프레드 연산자를 통해서 요소들만 추출한다.
이 과정에서 잘린 값들은 num_list에서 제거된다 (splice()는 원본을 변경하기 때문에)
그런 다음, num_list배열에 다시 push를 통해서 자른 값을 배열의 마지막에 추가한다.
🙋♀️ 내 생각
slice()와 splice()의 차이점을 더 명확하게 이해할 수 있었던 문제인것같다.
무조건 원본을 유지하는것만이 좋지 않을 수도 있고 상황에 따라 원본을 변경해야할때도 있기 때문에 splice()를 사용하는 방법도 알아두면 좋을 것 같다.
이번 문제를 풀면서 스프레드 연산자에 대해 자세하게 공부하고 이해하려고 노력하였다.
평소에는 문자열을 배열로 만들기위해서나, 리액트로 프로젝트를 할 때 원본을 변경하지 않으면서 배열을 복사하기 위해서 사용했었는데 자주 사용하고 유용한만큼 정확하게 알고 있으면 좋을것같다고 생각하여 공부하였다.
스프레드연산자를 함수의 호출시에 인자로 사용하는것과 배열의 중복을 쉽게 제거할 수 있는 것은 처음으로 알았다.
단순히 알고리즘을 푼다는 것이 아니라 자바스크립트를 조금이라도 더 이해할 수 있도록, 오늘 푼 문제에서 배울것은 무엇일까 고민하면서 공부하고 있다.
'JavaScript > 알고리즘' 카테고리의 다른 글
프로그래머스 글자지우기 JS ( for...of 반복가능한 객체를 간편하게 순회 ) (0) | 2023.06.25 |
---|---|
프로그래머스 문자열이 몇 번 등장하는지 세기 JS ( indexOf() 특징 ) (0) | 2023.06.24 |
프로그래머스 문자열 뒤집기 JS ( 문자열의 특정부분만 변경 / slice()의 범위 ) (0) | 2023.06.22 |
프로그래머스 세로읽기 JS ( 가로 m글자씩, 세로 c번째 적힌값찾기 ) (0) | 2023.06.21 |
프로그래머스 문자열 잘라서 정렬하기 JS (split()의 구분자가 문자열 끝에 위치한다면? / match()의 특징 ) (0) | 2023.06.20 |