Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트로 연속 요소 그룹화하기: 배열 압축 함수 구현 방법

대시(-)로 구분된 반복 단어들이 포함된 문자열이 다음과 같이 주어졌다고 가정해 보겠습니다.

const str = 'monday-sunday-tuesday-tuesday-sunday-sunday-monday-mondaymonday';

우리의 과제는 각 객체가 valuecount라는 두 개의 속성을 가진 객체 배열을 반환하는 함수를 작성하는 것입니다. 여기서 value는 문자열에 포함된 단어(monday, tuesday, sunday)를 의미하며, count는 해당 단어가 연속으로 나타난 횟수를 나타냅니다.

예를 들어 위 문자열의 경우 결과 배열은 다음과 같은 형태가 됩니다.

const arr = [{
    val: 'monday',
    count: 1
}, {
    val: 'sunday',
    count: 1
}, {
    val: 'tuesday',
    count: 2
}, {
    val: 'sunday',
    count: 2
}, {
    val: 'monday',
    count: 3
}]

그 이유는 monday가 한 번, sunday가 한 번, tuesday가 두 번, sunday가 두 번, 마지막으로 monday가 세 번 연속으로 나타나기 때문입니다.

해결 접근 방식

먼저 문자열을 대시(-) 기준으로 분할한 뒤, Array.prototype.reduce() 메서드를 활용하여 원하는 형태의 배열을 순차적으로 만들어낼 수 있습니다.

전체 코드는 다음과 같습니다.

예제 코드

const str = 'monday-sunday-tuesday-tuesday-sunday-sunday-monday-mondaymonday';
const str2 = 'friday-friday-sunday-tuesday-sunday-sunday-monday-thursdaymonday';

const compressString = (str) => {
    return str.split('-').reduce((acc, val) => {
        const { length: l } = acc;
        if(acc[l-1]?.val === val){
            acc[l-1].count++;
            return acc;
        }else{
            return acc.concat({
                val,
                count: 1
            });
        }
    }, []);
}

console.log(compressString(str));
console.log(compressString(str2));

코드 동작 원리

이 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다.

  • split('-'): 문자열을 대시 기준으로 분리하여 단어 배열을 생성합니다.
  • reduce(): 각 단어를 순회하면서 누적 배열(acc)의 마지막 요소와 현재 단어를 비교합니다.
  • 옵셔널 체이닝(?): 배열이 비어 있는 초기 상태에서 발생할 수 있는 오류를 안전하게 처리합니다.
  • 마지막 요소의 값이 현재 단어와 같으면 count를 1 증가시키고, 다르면 새로운 객체를 배열에 추가합니다.

이러한 방식은 시간 복잡도 O(n)으로 한 번의 순회만으로 연속 요소를 효율적으로 그룹화할 수 있다는 장점이 있습니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

[
    { val: 'monday', count: 1 },
    { val: 'sunday', count: 1 },
    { val: 'tuesday', count: 2 },
    { val: 'sunday', count: 2 },
    { val: 'monday', count: 3 }
]
[
    { val: 'friday', count: 2 },
    { val: 'sunday', count: 1 },
    { val: 'tuesday', count: 1 },
    { val: 'sunday', count: 2 },
    { val: 'monday', count: 1 },
    { val: 'thursday', count: 1 },
    { val: 'monday', count: 1 }
]