
“최대 2,000만원”처럼 문장으로 적힌 금액은 그대로는 정렬이 안 됩니다. 글자 순서로 줄을 세우면 “9백만원”이 “2천만원”보다 위로 올라옵니다. 이 글은 문장에서 숫자만 뽑아 비교용 값을 따로 만든 방법입니다.
보여줄 것과 비교할 것을 나눈다
핵심은 이겁니다. 화면에는 원래 문장을 그대로 보여주고, 정렬은 따로 뽑은 숫자로 합니다. 문장을 숫자로 바꿔 화면에 뿌리면 “최대”나 “월” 같은 조건이 사라져서 오해를 부릅니다.
단위를 표로 만든다
한국어 금액 표기는 단위가 정해져 있습니다. 억, 천만, 백만, 만, 천. 이걸 그냥 숫자와 짝지어 둡니다.
var unit = { '억':100000000, '천만':10000000, '백만':1000000, '만':10000, '천':1000 };var re = /(\d+(?:\.\d+)?)\s*(억|천만|백만|만|천)?원/g;단위가 없을 수도 있어서 물음표를 붙였습니다. “500000원”처럼 적힌 것도 있기 때문입니다.

가장 큰 값을 고른다
한 문장에 금액이 여러 개 나오는 경우가 많습니다. “월 50만원, 최대 600만원” 같은 식입니다. 이럴 때 큰 쪽을 씁니다. 목록에서 보고 싶은 건 보통 최대 금액이기 때문입니다.
function amountValue(value){ var text = String(value||'').replace(/,/g,''); // 쉼표를 먼저 없앤다 var max = 0, m; while ((m = re.exec(text))) { var amount = parseFloat(m[1]) * (unit[m[2]] || 1); // "50만원 × 12개월" 같은 표현을 잡는다 var tail = text.slice(m.index, re.lastIndex + 24); var multi = tail.match(/[×xX]\s*(?:최대\s*)?(\d+)\s*(?:개월|회|년)/); if (multi) amount *= parseInt(multi[1], 10); if (amount > max) max = amount; } return max;}맨 앞에서 쉼표를 먼저 지우는 것이 중요합니다. “2,000만원”에서 쉼표를 안 지우면 숫자를 “2”로만 읽습니다. 이것 때문에 한동안 정렬이 이상했습니다.
곱하기 처리는 나중에 붙였습니다. “월 50만원 × 12개월”이 “600만원”보다 아래에 오는 게 이상해서 넣었습니다. 뒤쪽 24글자만 보는 이유는, 너무 멀리까지 보면 다음 항목의 숫자를 끌어오기 때문입니다.

보여줄 때는 다시 사람 말로
정렬용 숫자는 화면에 안 씁니다. 대신 요약 표시가 필요할 때만 사람이 읽는 형태로 되돌립니다.
function formatWon(value){ if (value >= 100000000){ var eok = value / 100000000; return (Math.round(eok*10)/10).toLocaleString() + '억원'; } if (value >= 10000) return Math.round(value/10000).toLocaleString() + '만원'; return Math.round(value).toLocaleString() + '원';}억 단위만 소수점 한 자리를 남깁니다. “1.5억원”은 자연스럽지만 “1500.5만원”은 어색하기 때문입니다.
왜 글자 순서로는 안 되나
자바스크립트의 sort()는 비교 함수를 주지 않으면 각 요소를 문자열로 바꾼 뒤 UTF-16 코드 값 순서로 비교합니다. MDN 문서의 예시가 이 점을 잘 보여 줍니다. [1, 30, 4, 21, 100000]을 그냥 정렬하면 [1, 100000, 21, 30, 4]가 됩니다. 숫자로는 9가 80보다 작지만, 문자열로는 “80”의 첫 글자 8이 “9”의 9보다 앞서기 때문에 “80”이 먼저 나옵니다. 위에서 본 “9백만원”이 “2천만원”보다 위로 올라오는 것도 같은 원리입니다.
| 비교 방식 | MDN 예시 결과 | 의미 |
|---|---|---|
| 비교 함수 없음 | [1, 100000, 21, 30, 4] | 문자열 코드 값 순서 |
비교 함수 a - b | [1, 4, 21, 30, 100000] | 숫자 크기 순서 |
위 표의 두 번째 줄은 MDN이 설명한 a - b 비교 함수를 같은 배열에 적용한 값입니다.
비교 함수 쓸 때 알아 둘 점
MDN이 정리한 규칙을 이 글의 상황에 맞춰 옮기면 다음과 같습니다.
- 음수면 앞, 양수면 뒤, 0이면 같음. 내림차순으로 보여 주고 싶다면
b - a로 바꾸면 됩니다. - 빼기 방식은 NaN이 없을 때만 안전합니다. 금액을 못 읽어 NaN이 섞이면 순서가 엉킬 수 있어서, 이 글의 함수는 읽지 못한 값을 0으로 돌려줍니다.
- 정렬은 안정적입니다. ES2019 이후 같은 값끼리는 원래 순서를 유지합니다. 금액이 같은 두 항목이 있어도 새로고침할 때마다 자리가 바뀌지 않습니다.
- 원본 배열을 바꿉니다.
sort()는 제자리 정렬이라, 원래 순서를 남기려면 복사본을 정렬하거나toSorted()를 씁니다. undefined는 비교 함수가 불리지 않고 맨 끝으로 갑니다. 금액 칸이 비어 있는 항목이 맨 아래로 가는 것과 같은 결과입니다.
쉼표와 공백은 어떻게 읽히나
숫자로 바꾸는 단계에서도 규칙을 알아 두면 좋습니다. MDN의 parseFloat() 설명에 따르면 앞쪽 공백은 무시하고, 유효하지 않은 문자를 만나면 그 앞까지의 숫자만 돌려줍니다. 예를 들어 parseFloat("3.14some non-digit characters")는 3.14를 돌려주고, 첫 글자부터 숫자가 아니면 NaN이 됩니다. 쉼표는 숫자 표기에 쓰이는 문자가 아니므로 “2,000”을 그대로 넘기면 2에서 멈춥니다. 위에서 쉼표를 먼저 지우는 이유가 이것입니다.
| 입력 문장 | 처리 방식 | 정렬용 값 |
|---|---|---|
| 최대 2,000만원 | 쉼표 제거 후 2000 × 10000 | 20,000,000 |
| 월 50만원, 최대 600만원 | 두 금액 중 큰 쪽 | 6,000,000 |
| 월 50만원 × 12개월 | 곱하기 표현을 잡아 곱함 | 6,000,000 |
| 소득의 30% | 금액이 없어 읽지 못함 | 0 (맨 아래) |
문자열 그대로 정렬해야 한다면
금액이 아니라 “1회차, 2회차, 10회차”처럼 문자열 속 숫자를 정렬해야 한다면 Intl.Collator의 numeric 옵션이 대안입니다. MDN은 이 옵션을 “1” < “2” < “10” 순서가 되도록 숫자 단위로 비교하는 것이라고 설명하며, 기본값은 false입니다. ["10", "2", "1"]을 기본 설정으로 비교하면 ["1", "10", "2"]가 되고, numeric: true를 켜면 ["1", "2", "10"]이 됩니다. 다만 이 옵션은 “2천만원”처럼 한글 단위가 붙은 금액의 크기까지 계산해 주지는 않으므로, 이 글의 방식처럼 단위를 곱하는 단계는 여전히 필요합니다.
스프레드시트에서 정렬할 때
같은 목록을 스프레드시트로 정리한다면 Google 스프레드시트 도움말의 절차를 따르면 됩니다. 범위를 정렬할 때는 제목 행이 있으면 “데이터에 헤더 행이 있음” 옵션을 켜고, 첫 번째 정렬 열과 순서를 고른 뒤 정렬합니다. 시트 전체를 한 열 기준으로 정렬하려면 열 문자를 오른쪽 클릭해 A-Z 또는 Z-A 정렬을 고릅니다. 제목 행은 고정해 두면 작업 중에도 계속 보입니다. 이 도움말은 텍스트로 저장된 숫자를 다루지 않으므로, 금액을 문장으로 적어 둔 열은 이 글처럼 숫자 열을 따로 만들어 그 열로 정렬하는 편이 안전합니다.
단위표와 검증용 문장
앞에서 만든 단위표를 한눈에 정리하면 다음과 같습니다. 정렬이 맞는지 확인할 때는 아래 문장 몇 개를 넣어 보면 됩니다.
| 단위 | 곱하는 값 |
|---|---|
| 억 | 100,000,000 |
| 천만 | 10,000,000 |
| 백만 | 1,000,000 |
| 만 | 10,000 |
| 천 | 1,000 |
| 검증 문장 | 정렬용 값 | 이 문장으로 확인하는 것 |
|---|---|---|
| 9백만원 | 9,000,000 | 글자 순서 정렬에서는 2천만원보다 위에 오던 문제 |
| 2천만원 | 20,000,000 | 천만 단위 인식 |
| 500000원 | 500,000 | 단위 없이 적힌 금액 |
| 1.5억원 | 150,000,000 | 소수점이 있는 억 단위 |
| 월 30만원 × 6개월 | 1,800,000 | 곱하기 표현 |
| 소득의 30% | 0 | 읽지 못하는 표현이 맨 아래로 가는지 |
작은 값부터 오름차순으로 정렬하면 “소득의 30%”, “500000원”, “월 30만원 × 6개월”, “9백만원”, “2천만원”, “1.5억원” 순서가 되어야 합니다. 이 순서가 나오지 않으면 쉼표 제거, 단위 인식, 곱하기 처리 중 어느 단계에서 값이 달라졌는지 문장 하나씩 출력해 보면 찾을 수 있습니다. 화면에는 원래 문장을 그대로 보여 주고, 정렬에만 이 값을 쓴다는 원칙은 검증할 때도 그대로 유지합니다.
구현 전에 점검할 것
- 비교 함수가 숫자를 돌려주는지 확인합니다. 값이 없을 때 NaN이 아니라 0을 돌려줘야 합니다.
- 같은 금액끼리 순서가 흔들리지 않는지 봅니다. 최신 자바스크립트의 정렬은 안정적이라 따로 처리하지 않아도 됩니다.
- 원본 배열을 바꿔도 되는지 정합니다. 바뀌면 안 되는 목록이라면 복사본을 정렬합니다.
- 화면에 보이는 문장과 정렬용 숫자를 같은 항목에 나란히 보관해 두 값이 어긋나지 않게 합니다.
한계
못 읽는 표현이 아직 있습니다. “소득의 30%”처럼 비율로 적힌 것, “예산 범위 내”처럼 금액이 없는 것은 0으로 처리돼 맨 아래로 갑니다. 틀린 숫자를 만들어 내는 것보다는 낫다고 봤습니다.
그리고 이 값은 정렬용일 뿐 정확한 지원금액이 아닙니다. 실제 금액은 조건에 따라 달라지니, 화면에서는 반드시 원문을 같이 보여줘야 합니다.
확인 자료
- MDN: Array.prototype.sort()
- MDN: parseFloat()
- MDN: Intl.Collator() 생성자(numeric 옵션)
- Google 문서 편집기 고객센터: 스프레드시트 데이터 정렬
기준일: 2026-10-18