From: "Michael W. Ryder" <_mwryder@...> Date: 2007-05-04T15:15:05+09:00 Subject: Re: Is there a better way to do this? William James wrote: > On May 3, 9:03 pm, "Michael W. Ryder" <_mwry...@worldnet.att.net> > wrote: >> Dan Zwell wrote: >>>> I am trying to come up with a "generic" formatting routine so that I >>>> could feed it something like sform("123456789", "000-00-0000") or >>>> sform("1234567890", "(000) 000-0000") or sform("123456", "00/00/00") >>>> and it would work. I could easily do something like you suggest, and >>>> for some cases it might be better, but I want something I can for any >>>> number of formats. Thanks for the input. >>> welcome. >>> require 'enumerator' >>> def sform(num, fmt) >>> # convert num to array (of one digit strings): >>> num = num.to_enum(:each_byte).map { |code| code.chr } >>> # for each zero, replace it with a digit popped off the >>> # front of the array of numbers (or characters): >>> fmt.gsub(/0/) { num.shift } >>> end >>> dan >> Your method is much better than my C style one. With a little work to >> handle exceptions it should generally work. The only problem I have >> found so far is that it doesn't handle periods in the number string >> properly -- i.e. sform("12345.67", "$00,000.00") returns $12,345..6" >> instead of $12,345.67". Something for me to work on. Thanks for the code. > > I made some changes to handle the decimal point > and the case when there are fewer digits in the > string than in the format. > > # The part on the left of the decimal point. > def sform_left( str, fmt ) > result = '' > fmt = fmt.split(//) > str.split(//).reverse_each{|d| > while fmt.last != '0' do > result = fmt.pop + result > end > fmt.pop > result = d + result > } > result = fmt.first + result if fmt.first != '0' > result > end > > # The part on the right of the decimal point. > def sform_right( str, fmt ) > ary = str.split(//) > fmt.gsub( /0/ ){ ary.shift || '0' } > end > > def sform( str, fmt ) > str = str.split('.') > fmt = fmt.split('.') > result = sform_left( str[0], fmt[0]) > if fmt[1] > result += "." + sform_right( str.last, fmt.last) > end > result > end > > puts sform("12345", "$00,000") > puts sform("1234", "$00,000") > puts sform("123", "$00,000") > puts sform("12345.6", "$00,000.00") > puts sform("12345.678", "$00,000.00") > puts sform("12345.678", "$00,000") > > --- output --- > $12,345 > $1,234 > $123 > $12,345.60 > $12,345.67 > $12,345 > Thank you for the ideas. I figured there had to be a better way to accomplish what I wanted without doing it like I would do it in C. With a little work I think I can make these do everything I want to do. The last step I need to work on is to allow it to handle formats that replace leading zeros with blanks. This will allow the display of dollar amounts in neat columns.