在前端開發中,我們經常會遇到【將數字序號轉換為中文大寫數字】的需求——比如表單步驟條顯示“第一步”而非“第1步”、文章章節標題用“三”代替 “3”等。今天就帶大家拆解這個常見需求的實現思路,用TypeScript寫出簡潔又安全的轉換函數。
一、需求明確:我們要解決什么問題?
首先要明確核心訴求:輸入一個數字序號(如0、1、……9),輸出對應的中文大寫數字(如一、二、十)。
需要注意兩個細節:
- 序號的起始值:多數場景下序號從0開始(如數組索引),此時0對應一,1對應二;若序號從1開始,則1對應一,需根據業務調整映射關系。
- 邊界處理:當輸入超出預設范圍的數字(如僅支持0-9,卻輸入11),需返回合理結果(空字符串、默認值或拋錯),避免程序異常。
二、常見實現方案:從簡單到靈活
方案一:對象映射
這是最直觀的實現方式,適合固定范圍的序號轉換(如僅支持0-9的序號),代碼如下:
const numberToUpperCase = (num: number): string => {// 1. 定義數字與大寫漢字的映射關系const numberMap: { [key: number]: string } = {0: '一', 1: '二', 2: '三', 3: '四', 4: '五',5: '六', 6: '七', 7: '八', 8: '九'};// 2. 檢查輸入是否在映射范圍內,存在則返回對應值,否則返回空字符串return numberMap.hasOwnProperty(num) ? numberMap[num] : '';
};
代碼拆解:
- 類型安全:用{[key: number]: string}明確numberMap是“數字鍵—字符串值”的對象,避免鍵類型混亂。
- 映射邏輯:直接通過鍵值對綁定序號與大寫漢字,查找效率(O(1)),適合固定范圍場景。
- 邊界處理:用hasOwnProperty檢查輸入是否為有效鍵,避免訪問undefined;超出范圍返回空字符串,方便業務層做后續處理(如顯示"–")。
方案二:數組映射(更適合連續序號)
若序號是連續的整數范圍(如0-9),用數組映射比對象更簡潔——數組索引即序號,元素即對應大寫漢字:
const indexToChinese = (num: number): string => {const chineseList = [ '一', '二', '三', '四', '五', '六', '七', '八', '九'];// 邊界處理:超出范圍拋錯,更適合嚴格場景if (num < 0 || num >= chineseList.length) {throw new Error(`當前僅支持 0-${chineseList.length - 1} 的序號,輸入值:${num}`);}return chineseList[num];
};
方案對比:
特性 | 對象映射 | 數組映射 |
---|---|---|
適用場景 | 非連續序號 | 連續序號 |
查找效率 | O(1) | O(1) |
邊界處理 | 返回空字符串 | 拋錯(嚴格,適合強校驗) |
擴展性 | 需手動添加鍵值對 | 只需在數組尾部追加元素 |
方案三:進階優化:支持更大范圍的數字
以上兩種方案僅支持固定范圍,若需要轉換20以上甚至百位、千位的數字,硬編碼映射表就不現實了,需用算法動態生成:
const numberToChineseAdvanced = (num: number): string => {const digits = ['零', '一','二','三','四','五','六','七','八','九'];// 位數映射(十、百、千)const units = ['', '十','百','千'];// 邊界校驗if(num < 1 || num > 9999) {return '暫支持1-9999的數字轉換';}// 數字轉字符串, 按位處理const numStr = num.toString();let result = '';for(let i = 0; i < numStr.length; i++) {const digit = parseInt(numStr[i], 10);// 計算當前位數const position = numStr.length - 1 - i;if(digit !== 0) {// 非零result += digits[digit] +units[position];} else if(i < numStr.length - 1 && parseInt(numStr[i+1], 10) !== 0) {// 零的處理result += digits[digit]}}// 特殊處理 "十"開頭 如(10 =》 “十”,而非“一十”;11=》“十一”)if(numStr.length === 2 && numStr[0] === '1') {result = result.slice(1);}return result;
}
三、總結
數字序號轉中文大寫數字的實現,核心是【根據需求選擇合適的映射/算法方案】:
- 簡單固定范圍(如0-9):用對象/數組映射,代碼簡潔、性能高
- 大范圍數字(如1-9999):用算法動態生成,避免硬編碼
- 邊界處理:根據業務選擇“返回空字符串”或“拋錯”,保證程序穩定性
- TypeScript優勢:通過類型注解明確參數/返回值類型,減少類型錯誤