0

I have an array of string which contains the "firstname.lastname?some.xx" format strings:

customers = ["aaa.bbb?q21.dd", "ccc.ddd?ew3.yt", "www.uuu?nbg.xcv", ...]

Now, I would like to use this array to produce two arrays, with:

  • the element of the 1st array has only the string before "?" and replace the "." to a space.
  • the element of the 2nd array is the string after "?" and include "?"

That's I want to produce the following two arrays from the customers array:

1st_arr = ["aaa bbb", "ccc ddd", "www uuu", ...]

2nd_arr = ["?q21.dd", "?ew3.yt", "?nbg.xcv", ...]

What is the most efficient way to do it if I use customers array as an argument of a method?

def produce_two_arr customers
  #What is the most efficient way to produce the two arrays

  #What I did:
  1st_arr = Array.new
  2nd_arr = Array.new
  customers.each do |el|
    1st_Str, 2nd_Str=el.split('?')

    1st_arr << 1st_str.gsub(/\./, " ")
    2nd_arr << "?"+2nd_str
  end

  p 1st_arr
  p 2nd_arr
end
5
  • 3
    it seems pretty trivial, where exactly do you get stuck? show some code. Commented Nov 4, 2011 at 15:38
  • 1
    I agree; along with your previous question, I'd suggest making an effort first. You know how to create arrays, you know a few ways to iterate, you know how to do a replace. There's a split method on string. Commented Nov 4, 2011 at 15:49
  • I was about to post my answer, but agree. Look into the array (hint: map) and string documentation. Commented Nov 4, 2011 at 15:50
  • It looks like you edited the question. What kind of efficiency are you asking for: simplest code or fastest execution time? Commented Nov 4, 2011 at 15:57
  • Yep, I added my code already. I am looking for both, simplest code and fastest execution one. Just wanna learn from more experienced one Commented Nov 4, 2011 at 15:59

5 Answers 5

3

Functional approach: when you are generating results inside a loop but you want them to be split in different arrays, Array#transpose comes handy:

ary1, ary2 = customers.map do |customer|
  a, b = customer.split("?", 2)
  [a.gsub(".", " "), "?" + b]
end.transpose
Sign up to request clarification or add additional context in comments.

Comments

1

Anytime you're building an array from another, reduce (a.k.a. inject) is a great help:

But sometimes, a good ol' map is all you need (in this case, either one works because you're building an array of the same size):

a, b = customers.map do |customer|
  a, b = customer.split('?')
  [a.tr('.', ' '), "?#{b}"]
end.transpose

This is very efficient since you're only iterating through customers a single time and you are making efficient use of memory by not creating lots of extraneous strings and arrays through the + method.

4 Comments

Yeah, I think either option would work here. Map is probably clearer. I think I'll update.
no, no, you are now doing a map-inject frankenstein :-) Look at my answer, they are now equivalent. Note that you could always implement map with inject, but that's no reason to do it :-)
Not true; I think you may have caught an overly eager save.
oh, sorry. Indeed, I saw a .map do |result, costumer|.
0

Array#collect is good for this type of thing:

arr1 = customers.collect{ |c| c.split("?").first.sub( ".", "" ) }
arr2 = customers.collect{ |c| "?" + c.split("?").last }

But, you have to do the initial c.split("?") twice. So, it's effecient from an amount of code point of view, but more CPU intensive.

Comments

0
1st_arr = customers.collect{ |name| name.gsub(/\?.*\z/,'').gsub(/\./,' ') }

2nd_arr = customers.collect{ |name| name.match(/\?.*\z/)[0] }

Comments

0
array1, array2 = customers.map{|el| el.sub('.', ' ').split /(?:\?)/}.transpose

Based on @Tokland 's code, but it avoids the extra variables (by using 'sub' instead of 'gsub') and the re-attaching of '?' (by using a non-capturing regex).

Comments

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.