The code below is supposed to scan through a string and put a ',' before all zip codes. The code properly detects the zip codes and makes the change in x but the change is never reflected in thestring. How can I get these changes to exist outside of x's scope?
thestring.each do |x|
if x =~ /\d{5}/
puts "match"
x[-6] = ","
puts x
end
end
On Sep 27, 2004, at 4:39 PM, Matthew Margolis wrote:
The code below is supposed to scan through a string and put a ',' before all zip codes. The code properly detects the zip codes and makes the change in x but the change is never reflected in thestring. How can I get these changes to exist outside of x's scope?
thestring.each do |x|
if x =~ /\d{5}/
puts "match"
x[-6] = ","
puts x
end
end
The code below is supposed to scan through a string and put a ','
before all zip codes. The code properly detects the zip codes and makes
the change in x but the change is never reflected in thestring. How can
I get these changes to exist outside of x's scope?
thestring.each do |x|
if x =~ /\d{5}/
puts "match"
x[-6] = ","
puts x
end
end
The thing is, each substring, as returned by #each, is a new object,
so nothing you do to them affects the original string. You could
probably achieve what you want with:
Amendment: as James G. suggested, use gsub! if you have more than one
in one string Also make sure that you have no street numbers with
five digits in a row.
Amendment: as James G. suggested, use gsub! if you have more than one
in one string Also make sure that you have no street numbers with
five digits in a row.
David
Excellent. I didn't know that each returned new objects. Thanks a bunch guys.
"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.44.0409271452500.8281-100000@wobblini...
Hi --
> thestring.sub!(/\d{5}/) {|x| "#{x},"}
Amendment: as James G. suggested, use gsub! if you have more than one
in one string Also make sure that you have no street numbers with
five digits in a row.
The block variant isn't necessary in this case. A remark about
efficiency:
require 'benchmark'
REP = 1000
thestring = ("foo 12345 bar baz" * 100).freeze
Benchmark.bm(15) do |b|
b.report "direct" do
REP.times { thestring.gsub(/\d{5}/, ',\\&') }
end
b.report "direct group" do
REP.times { thestring.gsub(/(\d{5})/, ',\\1') }
end
b.report "block" do
REP.times { thestring.gsub(/\d{5}/) {|m| ",#{m}"} }
end
end
user system total real
direct 0.516000 0.000000 0.516000 ( 0.527000)
direct group 0.546000 0.000000 0.546000 ( 0.537000)
block 1.829000 0.000000 1.829000 ( 1.844000)
>Hi --
>
>On Tue, 28 Sep 2004, David A. Black wrote:
>
>
>
>> thestring.sub!(/\d{5}/) {|x| "#{x},"}
>>
>>
>
>Amendment: as James G. suggested, use gsub! if you have more than one
>in one string Also make sure that you have no street numbers with
>five digits in a row.
>
>
>David
>
>
>
Excellent. I didn't know that each returned new objects. Thanks a
bunch guys.
Just to clarify: it (each) doesn't always return new objects; it
depends on the particular case. For example, in the case of
Array#each, you do get the actual array element. With strings, the
effect is like splitting the string into lines, i.e., substrings.
Amendment: as James G. suggested, use gsub! if you have more than one
in one string Also make sure that you have no street numbers with
five digits in a row.
David
Excellent. I didn't know that each returned new objects. Thanks a bunch guys.
Just to clarify: it (each) doesn't always return new objects; it
depends on the particular case. For example, in the case of
Array#each, you do get the actual array element. With strings, the
effect is like splitting the string into lines, i.e., substrings.