[ 프로그래머스 | JS ] Lv. 1 K번째 수로 보는 자바스크립트의 배열 다루기

west·2024년 6월 18일

Algorithm

목록 보기
2/3

들어가기에 앞서

자바스크립트로 알고리즘을 푸는 건 처음이라(그동안 알고리즘은 자바로 풀었음) 일부러 정렬 파트에서 정답률 높은 문제를 골랐다. slice, splice, sort, 혹은 스프레드 문법 <- 이 정도만 알아도 바로 풀 수 있는 문제였지만.. 기왕 '자바스크립트'로 푸는 첫 번째 알고리즘 문제인 만큼 자스 배열 개념을 리마인드하면 좋을 것 같아 벨로그에 기록해봅니다요

splice() 메서드

원본 배열의 중간에 요소를 추가하거나 중간에 있는 요소를 제거하는 경우 splice 메서드를 사용한다.
splice 메서드는 세 개의 매개변수가 있으며 원본 배열을 직접 변경한다.

  • start: 원본 배열의 요소를 제거하기 시작할 인덱스다. star만 지정하면 원본 배열의 start부터 모든 요소를 제거한다. start가 음수일 경우 배열의 끝에서의 인덱스를 나타낸다.
  • deleteCount: 원본 배열의 요소를 제거하기 시작할 인덱스인 start부터 제거할 요소의 개수다. 제거할 요소 개수를 0으로 지정하면 아무런 요소도 제거하지 않고 새로운 요소들을 삽입한다.(옵션)
  • items: 제거한 위치에 삽입할 요소들의 목록이다. 생략할 경우 원본 배열에서 요소들을 제거하기만 하면 된다.(옵션)
const arr = [1, 2, 3, 4];

const result = arr.splice(1, 2, 20, 30);

console.log(result); // [2, 3] 제거한 요소가 배열로 반환됨 
console.log(arr); // [1, 20, 30, 4]

slice() 메서드

slice 메서드는 인수로 전달된 범위의 요소들을 복사하여 배열로 반환한다.
원본 배열은 변경되지 않으며, 두 개의 매개변수(start, end)를 갖는다.

slice 메서드는 원본 배열을 변경하지 않고, 복사본을 생성하여 반환하기 때문에 '얕은 복사'라고도 불린다. 첫 번째 인수(start)로 전달받은 인덱스부터 두 번째 인수(end)로 전달받은 인덱스 이전까지 요소(end는 미포함)들을 복사하여 배열로 반환한다.

const array = [1, 5, 2, 6, 3, 7, 4];

array.slice(0, 1); // [1] 
array.slice(2, 5); // [2, 6, 3]

console.log(array); // [1, 5, 2, 6, 3, 7, 4]

slice 메서드의 첫 번째 인수가 음수인 경우 배열의 끝에서부터 요소를 복사하여 배열로 변환한다.

const arr = [1, 2, 3];

arr.slice(-1); // [3]
arr.slice(-2); //[2, 3]

slice 메서드 인수를 모두 생략하면 원본 배열 복사본을 생성하여 반환한다.

const arr = [1, 2, 3];

const copy = arr.slice();
console.log(copy); // [1, 2, 3]
console.log(copy === arr); // false 

스프레드 문법

하나로 뭉쳐 있는 여러 값들의 집합을 펼쳐서(전개, 분산하여, spread) 개별적인 값들의 목록으로 만든다.

앞서 위에서 다룬 splice, slice는 ES5에서 배열의 중간에 다른 요소를 추가하거나 제거하기 위해, 혹은 배열을 복사하기 위해 쓰인 메서드이다. ES6에선 새로 도입된 스프레드 문법을 사용하면 더욱 간결하고 가독성 좋게 표현할 수 있다.

스프레드 문법을 사용할 수 있는 대상은 Array, String, Map, Set, DOM 컬렉션, arguments와 같이 for..of 문으로 순회할 수 있는 이터러블에 한정된다.

// [1, 2, 3]을 개별요소로 분리함 
console.log(...[1, 2, 3]); // 1 2 3 

console.log(...'Hello'); // H e l l o 

스프레드 문법의 결과물은 값으로 사용될 수 없고, 다음과 같이 쉼표로 구분한 값의 목록을 사용하는 문맥에서만 사용할 수 있다.

  • 함수 호출문의 인수 목록
  • 배열 리터럴의 요소 목록
  • 객체 리터럴의 프로퍼티 목록
const arr = [1, 2, 3];

// 스프레드 문법을 펼쳐서 arr을 1, 2, 3으로 펼쳐서 Math.max에 전달함 
const max = Math.max(...arr); // 3 

스프레드 문법은 Rest 파라미터와 형태가 동일하기 때문에 혼동할 수 있지만, Rest 파라미터함수에 전달된 인수들 목록을 배열로 전달받기 위해 매개변수 이름 앞에 ...을 붙이는 것이다. 스프레드 문법여러 개의 값이 하나로 뭉쳐 있는 배열과 같은 이터러블을 펼쳐서 개별적인 값들의 목록을 만드는 것이라 서로 반대의 개념임

function foo(...rest) {
  console.log(rest); // 1, 2, 3 -> [1, 2, 3]
}

foo(...[1, 2, 3]); // 1 2 3 
// ES5
let origin = [1, 2];
let copy = origin.slice();

console.log(copy); // [1, 2]

// ES6
let copy2 = [...origin];

console.log(copy2); // [1, 2]

sort() 메서드

sort 메서드는 배열의 요소를 정렬한다. 원본 배열을 직접 변경하며 정렬된 배열을 반환한다.

const fruits = ['Banana', 'Orange', 'Apple'];

fruits.sort();

console.log(fruits); // ['Apple', 'Banana', 'Orange']

sort 메서드는 유니코드 코드 포인트 순서를 따라 정렬하기 때문에 문자열 정렬에는 문제가 없다.
하지만! 숫자 배열을 정렬할땐 주의가 필요하다.
숫자 타입이라도 배열 요소를 문장려로 변환한 후 유니코드 코드 포인트 순서를 기준으로 정렬하기 때문에 가령 const arr = [2, 10] 의 배열을 sort()메서드로 정렬한다면 유니코드 코드 포인트 순서에 따라 [10, 2]로 정렬된다.

따라서, 숫자 요소를 정렬할 때는 sort 메서드에 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다.

const arr = [1, 2, 10];

arr.sort(); 
console.log(arr); // [1, 10, 2];

// 오름차순 정렬
arr.sort((a, b) => a - b); 
console.log(arr); // [1, 2, 10]; 

// 내림차순 정렬
arr.sort((a, b) => b - a);
console.log(arr); // [10, 2, 1]; 

배열 관련된 문법 정리는 여기까지! 이제 문제로 들어가봅시다


문제

배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.

예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면

array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.
1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.
2에서 나온 배열의 3번째 숫자는 5입니다.
배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한 사항

  • array의 길이는 1 이상 100 이하입니다.
  • array의 각 원소는 1 이상 100 이하입니다.
  • commands의 길이는 1 이상 50 이하입니다.
  • commands의 각 원소는 길이가 3입니다.

풀이 코드

slice() 메서드를 이용해서 배열 자른 거 복사한 후 스프레드 문법 이용하여 넣어주고 리턴처리 해줬다

function solution(array, commands) {
    var answer = [];
    var arr = [];
    // i ~ j 까지 자르고 정렬 후 k번째 숫자를 뽑으면 된다.
    for(let l = 0; l < commands.length; l++) {
        arr = [];
        let i = commands[l][0];
        let j = commands[l][1];
        let k = commands[l][2];
        arr = array.slice(i-1, j);
        // javascript의 sort() 함수는 문자열로 변환하여 정렬하기 때문에 유니코드 포인트 순서로 정렬됨 
        // 숫자 배열로 정렬하려면 아래와 같이 정렬해야함 
        arr.sort((a, b) => a - b);
        let num = arr[k-1];
        answer = [...answer, num];
    }
    return answer;
}
profile
산타 fe

0개의 댓글