From 6231140cd93a9b2215a625e04a3a031d3eee97b4 Mon Sep 17 00:00:00 2001 From: kailong321200875 <321200875@qq.com> Date: Fri, 2 Feb 2024 11:00:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/array/__test__/index.test.ts | 16 +++++++- src/array/index.ts | 14 +++++++ src/number/__test__/index.test.ts | 14 +++++++ src/number/index.ts | 41 ++++++++++++++++++++ src/string/__test__/index.test.ts | 54 +++++++++++++++++++++++++- src/string/index.ts | 64 ++++++++++++++++++++++++++++++- 6 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 src/number/__test__/index.test.ts create mode 100644 src/number/index.ts diff --git a/src/array/__test__/index.test.ts b/src/array/__test__/index.test.ts index 74ede67..8966764 100644 --- a/src/array/__test__/index.test.ts +++ b/src/array/__test__/index.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest' -import { findIndex, move } from '../index' +import { findIndex, move, shuffle } from '../index' describe('findIndex', () => { it('should return the index of the first element that satisfies the provided testing function', () => { @@ -40,3 +40,17 @@ describe('move', () => { expect(() => move([1, 2, 3], 5, 0)).toThrowError('Index out of bounds') }) }) + +describe('shuffle', () => { + it('should return an array with the same length', () => { + const ary = [1, 2, 3, 4, 5] + const shuffled = shuffle(ary) + expect(shuffled.length).toBe(ary.length) + }) + + it('should return an array with the same elements', () => { + const ary = [1, 2, 3, 4, 5] + const shuffled = shuffle(ary) + expect(shuffled.sort()).toEqual(ary.sort()) + }) +}) diff --git a/src/array/index.ts b/src/array/index.ts index e4e7e11..f938096 100644 --- a/src/array/index.ts +++ b/src/array/index.ts @@ -50,3 +50,17 @@ export const move = (ary: T[], fromIndex: number, toIndex: number): T[] ;[ary[fromIndex], ary[toIndex]] = [ary[toIndex], ary[fromIndex]] return ary } + +/** + * 数组乱序 + * @category Array + * @param ary 查找的数组 + * @returns 返回乱序后的数组 + * @example + * ``` typescript + * shuffle([1, 2, 3]) + * ``` + */ +export const shuffle = (ary: T[]): T[] => { + return ary.sort(() => Math.random() - 0.5) +} diff --git a/src/number/__test__/index.test.ts b/src/number/__test__/index.test.ts new file mode 100644 index 0000000..3e3ce2e --- /dev/null +++ b/src/number/__test__/index.test.ts @@ -0,0 +1,14 @@ +import { describe, it, expect } from 'vitest' +import { numberToChinese } from '../index' + +describe('numberToChinese', () => { + it('should convert numbers to Chinese currency format', () => { + expect(numberToChinese(123456.78)).toBe('壹拾贰万叁仟肆佰伍拾陆元柒角捌分') + expect(numberToChinese(100000000)).toBe('壹亿元整') + expect(numberToChinese(0)).toBe('零元整') + }) + + it('should handle negative numbers', () => { + expect(numberToChinese(-123456.78)).toBe('欠壹拾贰万叁仟肆佰伍拾陆元柒角捌分') + }) +}) diff --git a/src/number/index.ts b/src/number/index.ts new file mode 100644 index 0000000..d4464a3 --- /dev/null +++ b/src/number/index.ts @@ -0,0 +1,41 @@ +/** + * 数字转化为大写金额 + * @category Number + * @param {number} num + * @returns {string} + * @example + * ``` typescript + * numberToChinese(100) + * ``` + */ +export const numberToChinese = (num: number): string => { + const fraction = ['角', '分'] + const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'] + const unit = [ + ['元', '万', '亿'], + ['', '拾', '佰', '仟'] + ] + const head = num < 0 ? '欠' : '' + num = Math.abs(num) + let s = '' + for (let i = 0; i < fraction.length; i++) { + s += (digit[Math.floor(num * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '') + } + s = s || '整' + num = Math.floor(num) + for (let i = 0; i < unit[0].length && num > 0; i++) { + let p = '' + for (let j = 0; j < unit[1].length && num > 0; j++) { + p = digit[num % 10] + unit[1][j] + p + num = Math.floor(num / 10) + } + s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s + } + return ( + head + + s + .replace(/(零.)*零元/, '元') + .replace(/(零.)+/g, '零') + .replace(/^整$/, '零元整') + ) +} diff --git a/src/string/__test__/index.test.ts b/src/string/__test__/index.test.ts index 199854b..6d69b69 100644 --- a/src/string/__test__/index.test.ts +++ b/src/string/__test__/index.test.ts @@ -1,5 +1,13 @@ import { describe, it, expect } from 'vitest' -import { trim, underlineToHump, humpToUnderline, replace } from '../index' +import { + trim, + underlineToHump, + humpToUnderline, + replace, + phoneToAsterisk, + toCDB, + toDBC +} from '../index' describe('trim', () => { it('should remove spaces from both ends', () => { @@ -28,3 +36,47 @@ describe('replace', () => { expect(result).toBe('bbcdefg') }) }) + +describe('phoneToAsterisk', () => { + it('should replace the middle four digits with asterisks', () => { + expect(phoneToAsterisk('12345678901')).toBe('123****8901') + expect(phoneToAsterisk('98765432109')).toBe('987****2109') + }) + + it('should return the original string if it does not match the pattern', () => { + expect(phoneToAsterisk('12345')).toBe('12345') + expect(phoneToAsterisk('abcdefg')).toBe('abcdefg') + }) +}) + +describe('toCDB', () => { + it('should convert full-width characters to half-width', () => { + expect(toCDB('123456')).toBe('123456') + expect(toCDB('ABCDEF')).toBe('ABCDEF') + }) + + it('should convert full-width space to half-width', () => { + expect(toCDB(' ')).toBe(' ') + }) + + it('should leave half-width characters unchanged', () => { + expect(toCDB('123456')).toBe('123456') + expect(toCDB('ABCDEF')).toBe('ABCDEF') + }) +}) + +describe('toDBC', () => { + it('should convert half-width characters to full-width', () => { + expect(toDBC('123456')).toBe('123456') + expect(toDBC('ABCDEF')).toBe('ABCDEF') + }) + + it('should convert half-width space to full-width', () => { + expect(toDBC(' ')).toBe(' ') + }) + + it('should leave full-width characters unchanged', () => { + expect(toDBC('123456')).toBe('123456') + expect(toDBC('ABCDEF')).toBe('ABCDEF') + }) +}) diff --git a/src/string/index.ts b/src/string/index.ts index 5032c42..ec712fb 100644 --- a/src/string/index.ts +++ b/src/string/index.ts @@ -32,7 +32,7 @@ export const underlineToHump = (name: string): string => { } /** - * 驼峰字符串转下划线 + * 驼峰字符串转中划线 * @category String * @param str 驼峰字符串 * @example @@ -59,3 +59,65 @@ export const replace = (str: string, findText: string, repText: string) => { const regExp = new RegExp(findText, 'g') return str.replace(regExp, repText) } + +/** + * 手机号码中间四位替换成* + * @category String + * @param phone 手机号码 + * @example + * ``` typescript + * phoneToAsterisk('12345678901') + * ``` + * @returns 123****8901 + */ +export const phoneToAsterisk = (phone: string): string => { + return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') +} + +/** + * 全角转换为半角 + * @category String + * @param s 需要转换的字符串 + * @example + * ``` typescript + * toCDB('123456') + * ``` + * @returns 123456 + */ +export const toCDB = (s: string): string => { + const result = s.split('').map((char: string) => { + const code = char.charCodeAt(0) + if (code >= 65281 && code <= 65374) { + return String.fromCharCode(code - 65248) + } + if (code === 12288) { + return String.fromCharCode(32) + } + return char + }) + return result.join('') +} + +/** + * 半角转换为全角 + * @category String + * @param s 需要转换的字符串 + * @example + * ``` typescript + * toDBC('123456') + * ``` + * @returns 123456 + */ +export const toDBC = (s: string): string => { + const result = s.split('').map((char: string) => { + const code = char.charCodeAt(0) + if (code >= 33 && code <= 126) { + return String.fromCharCode(code + 65248) + } + if (code === 32) { + return String.fromCharCode(12288) + } + return char + }) + return result.join('') +}