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

Community
  • 1
  • 1
Mellon
  • 37,586
  • 78
  • 186
  • 264

3 Answers3

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
Paul Groves
  • 3,983
  • 2
  • 23
  • 24
  • Is .collect method more efficient than .each method ? – Mellon Nov 04 '11 at 15:17
  • 1
    @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 – WarHog Nov 04 '11 at 15:20
  • You don't necessarily need to `collect` if you're iterating and mangling in-place. – tadman Nov 04 '11 at 15:22
  • How about my case here : http://stackoverflow.com/questions/8011780/ruby-array-convert-to-two-arrays-in-my-case – Mellon Nov 04 '11 at 15:34
2

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

customers.collect!{ |name| name.split('.').join(' ') }
Thilo
  • 17,565
  • 5
  • 68
  • 84
  • Is .collect method more efficient than .each method ? – Mellon Nov 04 '11 at 15:16
  • The don't do the same thing. See for example http://stackoverflow.com/questions/5347949/whats-different-between-each-and-collect-method-in-ruby – Thilo Nov 04 '11 at 15:19
  • 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 Nov 04 '11 at 15:22
  • @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 :) – Thilo Nov 04 '11 at 15:33
  • Thanks all, how about my case here : http://stackoverflow.com/questions/8011780/ruby-array-convert-to-two-arrays-in-my-case – Mellon Nov 04 '11 at 15:36
  • 1
    The results of trying it are surprising to say the least. – tadman Nov 04 '11 at 15:36
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!('.', ' ') }
tadman
  • 208,517
  • 23
  • 234
  • 262