Array trouble

Hi

I want to add a value to an arrays’ values like this:

ret = “”
“abcd”.to_a.each do |w|
ret += " "
end

this gives => “abcd” in IRB
but I expected it to give "a b c d "

why doesnt this work as such?
thanks

gijs

On 19.10.2006 16:59, Gijs N. wrote:

but I expected it to give "a b c d "

why doesnt this work as such?

First, String#to_a does not what you probably expect:
irb(main):001:0> “abcd”.to_a
=> [“abcd”]

Here are workable solutions:

irb(main):002:0> “abcd”.gsub(/./, '\& ')
=> "a b c d "
irb(main):003:0> “abcd”.split(//).map {|s| s + " "}.join
=> "a b c d "

Kind regards

robert

Gijs N. wrote:

but I expected it to give "a b c d "
How about

“abcd”.split(‘’).join(’ ')

Peter
http://www.rubyrailways.com

This should work also:

'abcd'.scan(/./).join(' ')

Also:

“abcd”.split("").map do |w|
w + " "
end.join

would give you the extra space at the end.

Louis J Scoras wrote:

This should work also:

‘abcd’.scan(/./).join(’ ')

Yeah, but it has the same flaw as mine (as pointed out by Tom):
"a b c d " != “a b c d”

but

‘abcd’.scan(/./).join(’ ') + " "

resp

“abcd”.split(‘’).join(’ ') + " "

should solve also this problem…

Peter
http://www.rubyrailways.com

On 10/19/06, Gijs N. [email protected] wrote:

but I expected it to give "a b c d "

why doesnt this work as such?
thanks

Others have already given y

ou ways to do what you want to do. But I don’t think anyone answered
your question about why what you did doesn’t work.

Let’s pick it apart. First of all it doesn’t really return “abcd” it
returns [“abcd”] which is a array with a single element:

irb(main):001:0> ret = " "
irb(main):002:0> “abcd”.to_a.each do |w| ret += " "; end
=> [“abcd”]

So why is this?

First of all, the value of Array#each is the array itself:

irb(main):003:0> [1, 2].each {|el| puts el }
1
2
=> [1, 2]

And, as Robert pointed out, “abcd”.to_a doesn’t do what you expect, it
returns an array of lines in the string, and there’s only one line in
“abcd” so:

irb(main):004:0> “abcd”.to_a
=> [“abcd”]

Now your code looks like it’s trying to accumulate your result in ret,
lets’ run it again, but we’ll postpone the problem with String.to_a by
breaking up the array into characters, “by hand.”

irb(main):005:0* ret = " "
irb(main):006:0> [“a”, “b”, “c”, “d”].each { |w| ret += " " }
=> [“a”, “b”, “c”, “d”]
irb(main):007:0> ret
=> " "

Oops, we weren’t actually adding the elements, so ret just ended up as
a string with as many blanks as were characters. So let’s fix that:

irb(main):008:0> ret = " "
rb(main):009:0> [“a”, “b”, “c”, “d”].each { |w| ret += w + " " }
=> [“a”, “b”, “c”, “d”]
irb(main):010:0> ret
=> " a b c d "

Okay, that looks better.

Now others have given one way to break up the string into an array of
chars:

irb(main):011:0> “abcd”.split(//)
=> [“a”, “b”, “c”, “d”]

let’s put this solution of the to_a problem with what we just did:

irb(main):012:0>ret = ‘’
rb(main):013:0> “abcd”.split(//).each { |w| ret += w + " " }
=> [“a”, “b”, “c”, “d”]
irb(main):014:0> ret
=> " a b c d "

So this works, as do the others. One more way to do this which is
related to the approach we’ve been taking is to use inject.

irb(main):018:0> “abcd”.split(//).inject(“”) { |result, char| result
+= char + " " }
=> "a b c d "

This avoids having to use the auxiliary variable ret, since the result
of inject is the value accumulated in the first argument to it’s block
argument.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Thanks for all the replies, I really learned some important basics here.

Rick Denatale wrote:

On 10/19/06, Gijs N. [email protected] wrote:

but I expected it to give "a b c d "


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/