import { dropLastWhile , splitEvery } from './utils' ; const textSymbol = [ '' , '일' , '이' , '삼' , '사' , '오' , '육' , '칠' , '팔' , '구' ] ; const powerSymbol = [ '' , '십' , '백' , '천' ] ; const dotSymbol = [ '' , '만' , '억' , '조' , '경' ] ; const isInteger = ( num ) : boolean => isFinite ( num ) && Math . floor ( num ) === num ; const validate = ( num ) : number => ( isInteger ( num ) ? num : 0 ) ; const getAtomic = ( num ) : ( string | number ) [ ] [ ] => num . toString ( ) . split ( '' ) . map ( ( numText ) => parseInt ( numText , 10 ) ) . reverse ( ) . map ( ( item , index ) => { const powerIndex = index % 4 ; const dotIndex = Math . ceil ( index / 4 ) ; const power = item === 0 ? '' : powerSymbol [ powerIndex ] ; const dot = powerIndex === 0 ? dotSymbol [ dotIndex ] : '' ; return [ item , power , dot ] ; } ) ; const reduceAtomic = ( atomic ) : string [ ] => { const reduce = atomic . map ( ( item ) => { const newItem = [ ... item ] ; newItem [ 0 ] = textSymbol [ newItem [ 0 ] as number ] || '' ; return newItem . join ( '' ) ; } ) ; return splitEvery ( 4 , reduce ) . map ( ( item ) => ( dotSymbol . indexOf ( item . join ( '' ) ) > 0 ? [ '' , '' , '' , '' ] : item ) ) . reduce ( ( acc , val ) => acc . concat ( val ) , [ ] ) . reverse ( ) ; } ; const addSpacing = ( reduced ) : string => reduced . filter ( ( token ) => token ) . map ( ( token ) => { if ( dotSymbol . indexOf ( token . slice ( - 1 ) ) > 0 ) { return `${ token } ` ; } return token ; } ) . join ( '' ) . trim ( ) ; const removeOneStr = ( list ) : string [ ] => { if ( list . length === 1 ) { return list ; } const filtered = [ ] ; for ( let i = 0 ; i < list . length ; i += 1 ) { if ( i === list . length - 1 ) { filtered . push ( list [ i ] ) ; break ; } if ( list . length > 5 && dotSymbol . indexOf ( list [ i ] . slice ( 1 ) ) > 0 ) { filtered . push ( list [ i ] ) ; continue ; } if ( list [ i ] . slice ( 0 , 1 ) === textSymbol [ 1 ] ) { filtered . push ( list [ i ] . slice ( 1 ) ) ; } else { filtered . push ( list [ i ] ) ; } } return filtered ; } ; const getNormal = ( num ) : string => reduceAtomic ( getAtomic ( validate ( num ) ) ) . join ( '' ) ; const getLingual = ( num ) : string => removeOneStr ( reduceAtomic ( getAtomic ( validate ( num ) ) ) ) . join ( '' ) ; const getSpacing = ( num ) : string => addSpacing ( reduceAtomic ( getAtomic ( validate ( num ) ) ) ) ; const getLingualSpacing = ( num ) : string => addSpacing ( removeOneStr ( reduceAtomic ( getAtomic ( validate ( num ) ) ) ) ) ; const getMixed = ( num ) : string => { const mixedAtomic = getAtomic ( validate ( num ) ) . map ( ( item ) => `${ item [ 0 ] }${ item [ 2 ] }` ) ; const reduced = splitEvery ( 4 , mixedAtomic ) . map ( ( item ) => { const droppedZero = dropLastWhile ( ( x ) => parseInt ( x , 10 ) === 0 , item ) ; if ( droppedZero . length === 4 ) { droppedZero . splice ( 3 , 0 , ',' ) ; } return droppedZero ; } ) . reduce ( ( acc , val ) => acc . concat ( val ) , [ ] ) . reverse ( ) ; const result = addSpacing ( reduced ) ; return result === '' ? '0' : result ; } ; export const FormatOptions = { SPACING : 'spacing' , MIXED : 'mixed' , LINGUAL : 'lingual' , LINGUAL_SPACING : 'lingual_spacing' , } ; param num param formatOptions export function numToKorean ( num , formatOptions ? ) { if ( formatOptions === FormatOptions . SPACING ) { return getSpacing ( num ) ; } if ( formatOptions === FormatOptions . MIXED ) { return getMixed ( num ) ; } if ( formatOptions === FormatOptions . LINGUAL ) { return getLingual ( num ) ; } if ( formatOptions === FormatOptions . LINGUAL_SPACING ) { return getLingualSpacing ( num ) ; } return getNormal ( num ) ; }