0

I have an array of string which contains the "firstname.lastname" strings:

customers = ["aaa.bbb", "ccc.ddd", "www.uuu", "iii.oooo", ...]

Now, I would like to transfer each element's string format in the array by removing the "." and use space instead. That's I want the array to be:

customers = ["aaa bbb", "ccc ddd", "www uuu", "iii oooo", ...]

What is the most efficient way to do it?

---------------- MORE -------------------

And how about my case here

0

3 Answers 3

7
customers.collect!{|name| name.gsub(/\./, " ")}

Update

@tadman has it, here's my benchmarking FWIW

require 'benchmark'

customers = []
500000.times { customers << "john.doe" }

Benchmark.bm do|b|
  b.report("+= ") do
    # customers.collect!{|name| name.gsub(/\./, " ")} # 2.414220
    # customers.each { |c| c.gsub!(/\./, ' ') } # 2.223308
    customers.each { |c| c.tr!('.', ' ') } # 0.379226
  end
end
Sign up to request clarification or add additional context in comments.

4 Comments

Is .collect method more efficient than .each method ?
@Mellon, collect! is method for in-place working and after that you get changed collection. In case of each using you have to collect changed values by hand and that definitely not so efficent
You don't necessarily need to collect if you're iterating and mangling in-place.
2

Don't know if this is the most efficient, but it does the job:

customers.collect!{ |name| name.split('.').join(' ') }

6 Comments

Is .collect method more efficient than .each method ?
The don't do the same thing. See for example stackoverflow.com/questions/5347949/…
This seems like a really bad idea. split generates an Array object with multiple strings in it which are then discarded when the join operation occurs. gsub! will convert in-place, modifying the same object, so there's no garbage.
@tadman that may be true, but "efficient" is kind of ambiguous - does it mean fast or memory efficient? Split and join may use more memory but may still be faster. I don't know that, hence my qualifier in the answer, but I doubt it amounts to a "really bad" idea. Maybe just a "somewhat sloppy" idea :)
The results of trying it are surprising to say the least.
|
2

You can always just modify each value in-place:

customers.each { |c| c.gsub!(/\./, ' ') }

The alternatives, like collect! are more appropriate when you're switching the kind of object, not just altering the content of an existing object.

Note that this will mangle the original input, so if the String values in customers are frozen or need to be preserved in their initial form this won't work. This is probably not the case, but it is important to keep this in mind.

Update: After some benchmarking I've come to the conclusion that the fastest way to perform this operation is:

customers.each { |c| c.tr!('.', ' ') }

For those that are curious, here's a benchmark scaffold to experiment with.

  #     user     system      total        real
  # 0.740000   0.020000   0.760000 (  0.991042)
  list.each { |c| c.gsub!(/\./, ' ') }

  # 0.680000   0.010000   0.690000 (  1.011136)
  list.collect! { |c| c.gsub(/\./, ' ') }

  # 0.490000   0.020000   0.510000 (  0.628354)
  list.collect!{ |c| c.split('.').join(' ') }

  # 0.090000   0.000000   0.090000 (  0.103968)
  list.collect!{ |c| c.tr!('.', ' ') }

2 Comments

Correct you are. tr! it is.
Yay, second place! :) Nice solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.