views:

556

answers:

3

I have an array like so:

["marblecake", "also", "the", 1337]

I would like to get back a string which contains each element of the array prefixed by some specified string, then joined together by another specified string. For example,

["marblecake", "also", "the", 1337].join_with_prefix("%", "__")

should result in

# => %marblecake__%also__%the__%1337

How might I do this?

+3  A: 

If your array is in "a" then this one-liner will do it

a.map! { |k| "%#{k}" }.join("_")

You could easily put this in a function of your own - even add it to the Array class so that you can call it on an array, like in your example.

Cody Caughlan
Why are you using the destructive, in-place version of "map"? Depending on what the OP's code looks like, that could have some unintended side effects.
Jason Creighton
That did the trick. Thanks very much, Cody.
Kyle Kaitan
Jason: Only primitives/strings are being stored here. Is there an alternative you'd recommend?
Kyle Kaitan
"map" returns a new array. "map!" modifies the array that it's called on, and returns the same array. So if you have code that does. "a.map! { ... something ... }" and then later you reference "a" again, you'll find that the elements of "a" have been replaced with the result of the "map!" block, which you may or may not want. Unless you have a specific reason not to, I would just use "map", which returns a new array and doesn't touch the existing one.
Jason Creighton
Okay. Thanks for your help!
Kyle Kaitan
Jason, you're right, the bang version is destructive. I guess I figured that the coder would know the difference and implement appropriately. Maybe that is an unsafe assumption :)
Cody Caughlan
+1  A: 

As per the above suggestion:

class Array
  def join_with_prefix(prefix,separator)
    self.collect {|e| prefix.to_s + e }.join(separator)
  end
end

p ['ab','cd','ef'].join_with_prefix('%','__')
=> "%ab__%cd__%ef"
This assumes you are trying to join an array of strings - if you had an array of integers for instance than the " + e" part would fail as there as the "+" is not implemented for string + integer. A better approach would be to do the string concatenation in a double-quoted string with an string interpolation "#{e}" which would implicitly to_s your element, hence:self.collect {|e| "#{prefix}#{e}" }.join(separator)Its more flexible.
Cody Caughlan
Or you could just do `prefix.to_s + e.to_s`
rampion
A: 

All previous answers are extremely stupid. The simplest and the fastest method is this:

class Array
  def join_with_prefix(prefix, separator)
    prefix + self.join(separator + prefix)
  end
end
Oleg Andreev