Skip to content

Commit

Permalink
Optimize speed
Browse files Browse the repository at this point in the history
  • Loading branch information
narze committed Oct 11, 2021
1 parent 8cda6aa commit b31afb1
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 42 deletions.
99 changes: 58 additions & 41 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
const ONE = 'หนึ่ง';
const THREE_TO_NINE = ['สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า'];
const ED = 'เอ็ด';
const DIGITS = ['สิบ', 'ร้อย', 'พัน', 'หมื่น', 'แสน', 'ล้าน'];
const DIGIT = ['', 'สิบ', 'ร้อย', 'พัน', 'หมื่น', 'แสน'];
const ONES = ['', ED, 'สอง', ...THREE_TO_NINE];
const TENS = ['', ...['', 'ยี่', ...THREE_TO_NINE].map(t => t + DIGITS[0])];
const TENS = ['', ...['', 'ยี่', ...THREE_TO_NINE].map(t => t + DIGIT[1])];
const SUB_HUNDRED = TENS.flatMap(t => ONES.map(o => t + o));
SUB_HUNDRED[1] = ONE;
const SUB_TEN = [
'',
ONE,
'สอง',
...['สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า'],
];

function numberToWords(num: string): string {
let output = '';
let length = num.length;

Array.from(num).forEach((d, idx) => {
const digitIdx = (length - idx - 1) % 6;
const isMillion = length - 1 !== idx && digitIdx === 0;

if (d === '0') {
if (isMillion) {
output += 'ล้าน';
}

return;
}
const digit = DIGIT[digitIdx];
const unit = SUB_TEN[Number(d)];

const isSib = digitIdx === 1;

if (isSib && d === '1') {
output += digit;
} else if (isSib && d === '2') {
output += 'ยี่' + digit;
} else if (idx !== 0 && digitIdx === 0 && d === '1') {
output += 'เอ็ด';
} else {
output += unit + digit;
}

if (isMillion) {
output += 'ล้าน';
}
});

return output;
}

export function convert(input: number | string): string | boolean {
let baht: number;
Expand Down Expand Up @@ -37,6 +81,7 @@ export function convert(input: number | string): string | boolean {
if (baht < 0) {
isNegative = true;
baht = -baht;
bahtStr = baht.toString();
}
} else {
return false;
Expand All @@ -46,53 +91,25 @@ export function convert(input: number | string): string | boolean {
return 'ศูนย์บาทถ้วน';
}

const out = [];
let output = '';

// Baht
if (baht < 100) {
out.push(SUB_HUNDRED[baht]);
} else {
const digits: number[] = [];
Array.from(bahtStr).forEach(s => digits.unshift(+s));
const millionGroups = Array.from({ length: 1 + digits.length / 6 }, () =>
digits.splice(0, 6)
);

millionGroups.forEach((subMillion, mi) => {
if (mi) {
out.unshift('ล้าน');
}
subMillion.forEach((d, i) => {
if (i === 0) {
const n = d + Number(subMillion[1] || 0) * 10;
if (n === 1) {
out.unshift(ED);
} else {
out.unshift(SUB_HUNDRED[n]);
}
} else if (d && i !== 1) {
out.unshift(i ? DIGITS[(i - 1) % 6] : '');
out.unshift(SUB_HUNDRED[d]);
}
});
});
}

if (out[0] === ED) {
out[0] = ONE;
}
output += numberToWords(bahtStr);

// Satang
if (satang) {
if (baht) out.push('บาท');
out.push(SUB_HUNDRED[satang]);
out.push('สตางค์');
if (baht) output += 'บาท';

// Faster!
output += SUB_HUNDRED[satang] + 'สตางค์';
// output += numberToWords(satang.toString()) + 'สตางค์';
} else {
out.push('บาทถ้วน');
output += 'บาทถ้วน';
}

if (isNegative) {
out.unshift('ลบ');
output = 'ลบ' + output;
}

return out.join('');
return output;
}
41 changes: 40 additions & 1 deletion test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
import { convert } from '../src';
// const { ThaiBaht: thaiBahtText } = require('thai-baht-text-ts');
// import thaiBahtText from "thai-baht-text"

describe('convert', () => {
it('works', () => {
expect(convert(0)).toBe('ศูนย์บาทถ้วน');
expect(convert(1)).toBe('หนึ่งบาทถ้วน');
expect(convert(2)).toBe('สองบาทถ้วน');
expect(convert(5)).toBe('ห้าบาทถ้วน');
expect(convert(9)).toBe('เก้าบาทถ้วน');

expect(convert(10)).toBe('สิบบาทถ้วน');
expect(convert(20)).toBe('ยี่สิบบาทถ้วน');

expect(convert(30)).toBe('สามสิบบาทถ้วน');
expect(convert(45)).toBe('สี่สิบห้าบาทถ้วน');

expect(convert(100)).toBe('หนึ่งร้อยบาทถ้วน');
expect(convert(122)).toBe('หนึ่งร้อยยี่สิบสองบาทถ้วน');
expect(convert(190)).toBe('หนึ่งร้อยเก้าสิบบาทถ้วน');

expect(convert(290)).toBe('สองร้อยเก้าสิบบาทถ้วน');

expect(convert(1000)).toBe('หนึ่งพันบาทถ้วน');
expect(convert(10000)).toBe('หนึ่งหมื่นบาทถ้วน');
expect(convert(100000)).toBe('หนึ่งแสนบาทถ้วน');

expect(convert(1000000)).toBe('หนึ่งล้านบาทถ้วน');
expect(convert(1002000)).toBe('หนึ่งล้านสองพันบาทถ้วน');

expect(convert(10000000)).toBe('สิบล้านบาทถ้วน');
expect(convert(10002000)).toBe('สิบล้านสองพันบาทถ้วน');
});

it('returns false for bad inputs', () => {
expect(convert(('hello' as unknown) as number)).toBe(false);
expect(convert('hello')).toBe(false);
expect(convert((false as unknown) as number)).toBe(false);
expect(convert((true as unknown) as number)).toBe(false);
expect(convert(({} as unknown) as number)).toBe(false);
Expand Down Expand Up @@ -130,4 +162,11 @@ describe('convert', () => {
'สี่ล้านหนึ่งแสนสองหมื่นสามพันเอ็ดล้านเก้าแสนเก้าหมื่นแปดพันแปดร้อยสามสิบล้านเจ็ดแสนห้าหมื่นห้าร้อยเอ็ดบาทถ้วน'
);
});

// it("equals to value from thai-baht-text-ts library", () => {
// console.log(10056518, convert(10056518), thaiBahtText(10056518))
// for (let i = 1; i < 20000000; i += 1) { // Math.floor(Math.random() * 10000)) {
// expect(convert(i)).toEqual(thaiBahtText(i));
// }
// })
});

0 comments on commit b31afb1

Please # to comment.