views:

323

answers:

3

I have 4 string variables name, quest, favorite_color, speed that might be empty. I want to concatenate them all together, putting spaces between those that aren't empty.

So:

name = 'Tim'
quest = 'destroy'
favorite_color = 'red'
speed = 'fast'

becomes

'Tim destroy red fast'

and

name = 'Steve'
quest = ''
favorite_color = ''
speed = 'slow'

becomes:

'Steve slow'

(Notice: there is only 1 space between 'Steve' and 'slow')

How do I do that (preferably in 1 line)?

EDIT: should have put this earlier. Simplicity of the code (IE how simple is to to look at and understand) is more important than speed.

+3  A: 

You can use inject:

[name,quest,favorite_color,speed].inject("") {|k,v| v.empty? ? k : k << " " << v }.strip
Joshua Smith
+1 for a working answer, although it's less easy to read (and thus upkeep) than the others.
David Oneill
You are correct on all points. Aaron's answer is better.
Joshua Smith
+13  A: 
[name, quest, favorite_color, speed].reject(&:empty?).join(' ')
Aaron Hinni
When I test this, I get the following error: "Error on line 5: wrong argument type Symbol (expected Proc)" What am I missing?
David Oneill
Probably you're using Ruby <1.8.7. Try `[name, quest, favorite_color, speed].reject{|s| s.empty?}.join(' ')`
Mladen Jablanović
What version of Ruby? Could also try:[name,quest,favorite_color,speed].reject {|s| s.empty?}.join(' ')
Aaron Hinni
Yep, that did it. Ruby 1.8.2 BTW. Thanks guys!
David Oneill
Ruby is so elegant.
macek
+6  A: 

Try [name,quest,favorite_color,speed].join(' ').squeeze(' ')

bta
this one seems simplest.
Allyn
It's also the fastest.
ghoppe
This will only pull out spaces. But if there are spaces in the individual string, I can't have them removed.
David Oneill
It won't pull out spaces in the individual string, only multiple consecutive spaces. This may or may not be a problem for you. If this is some sort of language parser, I would count it as a plus.
ghoppe
There is a very good chance there will never be multiple consecutive spaces in the initial strings, but I can't risk that.
David Oneill
It's not the fastest either.
Mladen Jablanović
You can also use a non-space character for 'join' and 'squeeze' (one that will never appear in your input) and then replace all instances of that character with a space.
bta
It was fastest by a significant margin (~50%) in my testing. Platform? Proof?
ghoppe
@ghoppe: http://pastie.org/866908
Mladen Jablanović
@David Upvote for asking a moderately beginner ruby question, but actually understanding the ramifications of various answers.
Myrddin Emrys
@David, I don't understand why you're worried about tidying spaces if you might have spaces in the strings. Are you sure you're specifying the proper delimiter? Should you be quoting the values?`
glenn jackman
+1 @bta's comment. @Myrddin Thx. I am a beginner in Ruby, but I'm learning. @glenn: I have to accurately pull over the original strings. If it wasn't possible to do that, I would have just left the extra spaces in.
David Oneill