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

JavaScript - 문자열 배열에서 숫자 합이 가장 큰 신용카드 번호 찾는 법

문제 상황

다음과 같이 데모용 신용카드 번호들이 담긴 배열이 있다고 가정해 보겠습니다.

const arr = ['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260'];

이 배열을 인자로 받아 각 번호에서 숫자의 합이 가장 큰 신용카드 번호를 반환하는 함수를 작성해야 합니다. 만약 서로 다른 카드 번호가 같은 합을 가진다면, 그중 마지막에 위치한 카드 번호를 반환해야 한다는 조건이 붙습니다.

해결 접근 방식

이 문제는 다음과 같은 단계로 풀어갈 수 있습니다.

① 각 카드 번호 문자열을 하이픈(-)을 기준으로 분리합니다.
② 분리된 각 조각을 숫자로 변환한 뒤 모두 더해 합계를 구합니다.
③ 배열의 모든 카드 번호에 대해 위 과정을 반복하며 합계 목록을 만듭니다.
④ 합계 목록에서 최댓값을 찾고, 그 값이 마지막으로 등장하는 인덱스를 구합니다.
⑤ 해당 인덱스에 있는 원본 카드 번호를 결과로 반환합니다.

예제 코드

const arr = ['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260'];
const findGreatestNumber = (arr) => {
    let n, i = 0, sums;
    sums = [];
    while (i < arr.length) {
        sums.push(sum(arr[i]));
        i++;
    }
    n = sums.lastIndexOf(Math.max.apply(null, sums));
    return arr[n];
}
const sum = (num) => {
    let i, integers, res;
    integers = num.split(/[-]+/g);
    i = 0;
    res = 0;
    while (i < integers.length) {
        res += Number(integers[i]);
        i++;
    }
    return res;
};
console.log(findGreatestNumber(arr));

코드 설명

sum() 함수는 정규 표현식 /[-]+/g를 사용해 카드 번호 문자열을 하이픈 기준으로 분리하고, 각 조각을 Number()로 변환해 하나씩 누적한 합계를 반환합니다.

findGreatestNumber() 함수는 while 루프를 돌며 각 카드 번호의 합계를 sums 배열에 차례대로 저장합니다. 이후 Math.max.apply(null, sums)로 최댓값을 구하고, lastIndexOf()로 그 값이 마지막으로 등장하는 인덱스를 찾습니다. 덕분에 최댓값이 여러 번 나타나더라도 항상 뒤쪽에 있는 카드 번호가 선택되어, 문제에서 요구한 조건을 그대로 만족합니다.

더 간결한 ES6 버전

map(), reduce(), 전개 연산자(spread operator)를 활용하면 같은 로직을 훨씬 짧고 읽기 쉽게 표현할 수 있습니다.

const arr = ['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260'];

// 하이픈으로 구분된 각 숫자 조각의 합을 계산하는 함수
const digitSum = num =>
  num.split('-').reduce((acc, cur) => acc + Number(cur), 0);

// 합계 배열에서 최댓값이 마지막으로 등장하는 인덱스를 찾아 반환
const findGreatestNumber = arr => {
  const sums = arr.map(digitSum);
  return arr[sums.lastIndexOf(Math.max(...sums))];
};

console.log(findGreatestNumber(arr));

실행 결과

콘솔에는 다음과 같이 출력됩니다.

4252-278893-7978

네 개의 카드 번호 중 '4252-278893-7978'의 숫자 합이 가장 크기 때문에 이 번호가 최종 결과로 반환됩니다.