[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Is there a better way to do this?

Michael W. Ryder

5/4/2007 12:44:00 AM

As part of my learning Ruby I am trying to learn how to format strings.
The following is an example for formatting a U.S. phone number:

a = "1234567890"
b = "(000) 000-0000"
ai = 0

for i in 0..(b.length) -1
if b[i,1] == "0"
b[i,1] = a[ai,1]
ai += 1
end
end
puts b

Is there a better (more Rubyish) way to do this?
Obviously I will want to add more code in the future to handle
exceptions like phone numbers that are not 10 characters long or are
longer, but this will get me started.
18 Answers

Harry Kakueki

5/4/2007 1:17:00 AM

0

On 5/4/07, Michael W. Ryder <_mwryder@worldnet.att.net> wrote:
> As part of my learning Ruby I am trying to learn how to format strings.
> The following is an example for formatting a U.S. phone number:
>
> a = "1234567890"
> b = "(000) 000-0000"
> ai = 0
>
> for i in 0..(b.length) -1
> if b[i,1] == "0"
> b[i,1] = a[ai,1]
> ai += 1
> end
> end
> puts b
>
> Is there a better (more Rubyish) way to do this?
> Obviously I will want to add more code in the future to handle
> exceptions like phone numbers that are not 10 characters long or are
> longer, but this will get me started.
>
>
I'm sure there are better ways but here is something to look at.

a = "1234567890"
area = a.slice(0..2)
exc = a.slice(3..5)
num = a.slice(6..9)
tel = "(#{area}) #{exc}-#{num}"

p tel

Harry


--
http://www.kakueki.com/ruby...
A Look into Japanese Ruby List in English

Michael W. Ryder

5/4/2007 1:23:00 AM

0

Harry Kakueki wrote:
> On 5/4/07, Michael W. Ryder <_mwryder@worldnet.att.net> wrote:
>> As part of my learning Ruby I am trying to learn how to format strings.
>> The following is an example for formatting a U.S. phone number:
>>
>> a = "1234567890"
>> b = "(000) 000-0000"
>> ai = 0
>>
>> for i in 0..(b.length) -1
>> if b[i,1] == "0"
>> b[i,1] = a[ai,1]
>> ai += 1
>> end
>> end
>> puts b
>>
>> Is there a better (more Rubyish) way to do this?
>> Obviously I will want to add more code in the future to handle
>> exceptions like phone numbers that are not 10 characters long or are
>> longer, but this will get me started.
>>
>>
> I'm sure there are better ways but here is something to look at.
>
> a = "1234567890"
> area = a.slice(0..2)
> exc = a.slice(3..5)
> num = a.slice(6..9)
> tel = "(#{area}) #{exc}-#{num}"
>
> p tel
>
> Harry
>
>
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.

Dan Zwell

5/4/2007 1:39:00 AM

0

> 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

Harry Kakueki

5/4/2007 1:44:00 AM

0

> >
> 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.
>
>
Well, that's different :)
So, you want to grab the first 10 digits and ignore beyond that?
Look into regular expressions.
Harry

--
http://www.kakueki.com/ruby...
A Look into Japanese Ruby List in English

Michael W. Ryder

5/4/2007 2:03:00 AM

0

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.

William James

5/4/2007 2:06:00 AM

0

On May 3, 8:38 pm, Dan Zwell <dzw...@gmail.com> 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

Without 'enumerator':

def sform( str, fmt )
ary = str.split(//)
fmt.gsub( /0/ ){ ary.shift }
end

Harry Kakueki

5/4/2007 2:09:00 AM

0

On 5/4/07, Harry Kakueki <list.push@gmail.com> 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.
> >
> >
> Well, that's different :)
> So, you want to grab the first 10 digits and ignore beyond that?
> Look into regular expressions.
> Harry
>
> --
> http://www.kakueki.com/ruby...
> A Look into Japanese Ruby List in English
>
>
This will grab digits and then you can do what you want with them.

arr = ["1234567890", "(123) 867-5309","12/34/56/78/90444"]

arr.each do |x|
num = x.scan(/\d/).join
p num
puts
end

Harry


--
http://www.kakueki.com/ruby...
A Look into Japanese Ruby List in English

Dan Zwell

5/4/2007 2:19:00 AM

0

> def sform( str, fmt )
> ary = str.split(//)
> fmt.gsub( /0/ ){ ary.shift }
> end
>
>

Yeah, that's much simpler. I like it.

Dan

William James

5/4/2007 3:02:00 AM

0

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

Harry Kakueki

5/4/2007 5:12:00 AM

0

On 5/4/07, Michael W. Ryder <_mwryder@worldnet.att.net> 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.
>
>

I was thinking about your question again and came up with this.
Just before I posted I saw that William had taken a similar approach
and offered it in a more compact form.
Anyway , for what it's worth.
I was thinking the dots should only be in the formatting, not in the
input so I stripped them out of the input.

#arr = ["123456", "00/00/00"]
arr = ["12345.67", "$00,000.00"]
#arr = ["1234567890", "(000) 000-0000"]

inp_arr = arr[0].delete(".").split(//)
fmt_arr = arr[1].split(//)
str = ""
fmt_arr.each do |x|
str << inp_arr.shift if x =~ /\d/
str << x if x !~ /\d/
end
p str

Harry


--
http://www.kakueki.com/ruby...
A Look into Japanese Ruby List in English