keep changes in string outside of scope?

M

Matthew Margolis

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


Thank you,
Matthew Margolis
 
J

James Edward Gray II

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

What about:

thestring.gsub!(/(\d{5})/, '\1')

That help?

James Edward Gray II
 
D

David A. Black

Hi --

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:

thestring.sub!(/\d{5}/) {|x| "#{x},"}


David
 
D

David A. Black

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.


David
 
M

Matthew Margolis

David said:
Hi --



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.

-Matt Margolis
 
D

David A. Black

Hi --

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.


David
 
M

Matthew Margolis

David said:
Hi --



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.


David
Understood.

-Matt Margolis
 
R

Robert Klemme

James Edward Gray II said:
Oops, forgot the period. The replace string should be '.\1'. Sorry

He wanted a comma...
:)

And without diving too far into escape handling I'd use

thestring.gsub!(/\d{5}/, ',\\&')

Note also, that you don't need the grouping.

robert
 
R

Robert Klemme

David A. Black said:
Hi --



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)


Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top