[프로그래머스-기초] 빈 배열에 추가, 삭제하기

JE·2024년 1월 8일
0

코테/코플릿

목록 보기
46/57

빈 배열에 추가, 삭제하기

문제 설명

아무 원소도 들어있지 않은 빈 배열 X가 있습니다. 길이가 같은 정수 배열 arr과 boolean 배열 flag가 매개변수로 주어질 때, flag를 차례대로 순회하며 flag[i]가 true라면 X의 뒤에 arr[i]를 arr[i] × 2 번 추가하고, flag[i]가 false라면 X에서 마지막 arr[i]개의 원소를 제거한 뒤 X를 return 하는 solution 함수를 작성해 주세요.

제한사항

1 ≤ arr의 길이 = flag의 길이 ≤ 100
arr의 모든 원소는 1 이상 9 이하의 정수입니다.
현재 X의 길이보다 더 많은 원소를 빼는 입력은 주어지지 않습니다.

입출력 예

arrflagresult
[3, 2, 4, 1, 3][true, false, true, false, false][3, 3, 3, 3, 4, 4, 4, 4]

입출력 예 설명

입출력 예 #1

예제 1번에서 X의 변화를 표로 나타내면 다음과 같습니다

iflag[i]arr[i]X
0true3[3, 3, 3, 3, 3, 3]
1false2[3, 3, 3, 3]
2true4[3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4]
3false1[3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4]
4false3[3, 3, 3, 3, 4, 4, 4, 4]

따라서 [3, 3, 3, 3, 4, 4, 4, 4]를 return 합니다.

💻 내가 작성한 코드

function solution(arr, flag) {
    let result = [];

    for(let i = 0; i < flag.length; i++) {
        if(flag[i]){
           result.push(...Array(arr[i] * 2).fill(arr[i]))  
        } 
        else {
            result.splice(result.length - arr[i], arr[i])
        }
    }

    return result;
}

result라는 빈 배열을 선언한다.
flag를 순환 하면서

만약 flag[i]가 ture일 경우

Array(arr[i] * 2).fill(arr[i]))
요소 곱하기 2한 배열의 수에 해당 요소로 채워준다.
그런 다음 result.push(...Array(arr[i] * 2).fill(arr[i]))

result에 push해주는데 spread syntax문법을 사용해 배열을 풀어준 상태로 push한다.
만약 그냥 push할 경우 [[...]] 처럼 배열 안에 배열이 생성된다.

만약 flag[i]가 false일 경우

result.splice(result.length - arr[i], arr[i])
splice메소드를 사용해 result길이에서 arr[i] 요소 만큼 뺀 index에서 arr[i]만큼 제거해 준다.

예를 들어

const months = ['Jan', 'March', 'April', 'June'];
months.splice(months.length - 2, 2);
// Array ["Jan", "March"]

months.splice(months.length - 2, 2);를 풀어보면
months.splice(2, 2)가 된다.

index는 0부터 세고 length는 1 부터 센다.

먼저 첫번째 매개변수 2는 시작할 index이다. 즉, 'April'부터 2개의 요소를 제거한다.
그러므로 ["Jan", "March"]가 남게 된다.

배열을 순환하는 메소드로도 풀 수 있는데
나는 forEach로 리팩토링 해 봤다.

🛠️ 리팩토링 해 보기 다르게 풀어보기

function solution(arr, flag) {
    let result = [];
    
    flag.forEach((el, idx) => (
        el 
        ? result.push(...Array(arr[idx] * 2).fill(arr[idx]))  
        : result.splice(result.length - arr[idx], arr[idx])
    ))
    
    return result;
}

forEach와 삼항 연산자를 사용했다.
flag의 요소 자체가 boolean이기 때문에 요소(el)가 true/flase냐에 따라
다르게 표시 했다.

리팩토링 보단... 다르게 풀어본 방법이 맞을 수도 있겠다.

💻 다른 사람이 푼 코드

function solution(arr, flag) {
  return arr.reduce(
    (prev, num, i) => (flag[i] ? [...prev, ...new Array(num * 2).fill(num)] : prev.slice(0, -num)),
    [],
  );
}

reduce를 사용해 푸셨는데 정말 간단하게 작성하셨다.

[...prev, ...new Array(num * 2).fill(num)] 여기는 내가 작성한 코드와 비슷하지만 다른 점은

prev.slice(0, -num) flase인 경우 기존 배열에서 slice를 이용해 해당 값 만큼 자른 값을 반환하는 것 같다.

이점은 다시 코드를 분석해 봐야겠다.


✏️ 마치며

이번 문제 풀이 덕분에 splice 메소드에 대해 제대로 알아가는 것 같다.

profile
[프론트 애송이] 작은 깨달음도 기록하기

0개의 댓글