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
···
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 have a vague recollection that Perl has a specific feature along these
lines: ah yes, see "man perlform". But I've never used it, and I think this
is one Perlism that Ruby hasn't copied.
It sounds to me like you actually want two different types of format:
You can even add exceptions and special handling if one of the parts is missing etc. If you need leading zeros, that's easy with sprintf as well.
Kind regards
robert
···
On 04.05.2007 02:43, Michael W. Ryder 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.
when you have other formats, use if a.length == whatever to decide which
pattern to apply.
--Ken
···
On Fri, 04 May 2007 00:43:34 +0000, Michael W. Ryder 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.
--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/
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.
I answered that question, too.
But then he added more requirements.
He not only wants to deal with phone number formats, but any format.
Harry
···
On 5/4/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> 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'd start by having the parts of the number separate. Then you can
easily use sprintf for the formatting. For example, with
Phone = Struct.new(:country, :area, :number) do
def to_s
sprintf("(%d) %d-%d", country, area, number)
end
end
On Fri, 04 May 2007 00:43:34 +0000, Michael W. Ryder 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.
puts a.sub(/(...)(...)(....)/,'(\1) \2-\3')
when you have other formats, use if a.length == whatever to decide which pattern to apply.
--Ken
That looks very interesting! Thanks for the code. I think it will work great for parts of the method. With very little work this I can make this work for formatting dollar amounts, etc.
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
>
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
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.
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
···
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 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.
arr.each do |x|
num = x.scan(/\d/).join
p num
puts
end
Harry
···
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
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
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
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.
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
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.