JavaScript/알고리즘

프로그래머스 순서 바꾸기 JS (slice(), ... 스프레드연산자 Spread Operator / splice() )

hihiha2 2023. 6. 23. 17:39
반응형

문제 설명

정수 리스트 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()를 사용하는 방법도 알아두면 좋을 것 같다.

 

이번 문제를 풀면서 스프레드 연산자에 대해 자세하게 공부하고 이해하려고 노력하였다.

평소에는 문자열을 배열로 만들기위해서나, 리액트로 프로젝트를 할 때 원본을 변경하지 않으면서 배열을 복사하기 위해서 사용했었는데 자주 사용하고 유용한만큼 정확하게 알고 있으면 좋을것같다고 생각하여 공부하였다.

 

스프레드연산자를 함수의 호출시에 인자로 사용하는것과 배열의 중복을 쉽게 제거할 수 있는 것은 처음으로 알았다.

 

단순히 알고리즘을 푼다는 것이 아니라 자바스크립트를 조금이라도 더 이해할 수 있도록, 오늘 푼 문제에서 배울것은 무엇일까 고민하면서 공부하고 있다. 

 

반응형