why does ruby parallel assignment with array of strings returns string
a, b = ["ho", "hey"]
a
is assigned the first element of the array, which is the string "ho". Nothing weird.a, b = ["blerg"], ["baz"]
a, b = [["blerg"], ["baz"]]
These two are the same, as you can see by their return values. So a is assigned the first element, which is an array with one element: ["blerg"]
.Similarly,
c, d = "foo", "bar"
Is the same asc, d = ["foo", "bar"]
Why does parallel assignment of a single empty array assign multiple nils?
I believe this example will help you understand the problem:
[1] pry(main)> a, b, c = [1,2]
=> [1, 2]
[2] pry(main)> a
=> 1
[3] pry(main)> b
=> 2
[4] pry(main)> c
=> nil
Now back to your problem, you are trying to assign the elements in an empty array to variables, as a result, the three variables all get nil value. ruby split string into array then split array elements into words
"hello world".split.map { |word| word[-1] + word[1..-2] + word[0] }.join(' ')
=> "oellh dorlw"
Swapping array elements using parallel assignment
It is expected. It follows from how ruby evaluates expressions.
deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]
Impliesdeck[deck.index("A")], deck[deck.index("B")] = 'B', 'A'
Note: strings 'A' and 'B' here are for illustration only. Ruby doesn't create new string objects here. Which essentially is:deck[deck.index("A")] = 'B' -> deck[0] = 'B' (deck = ['B', 'B', 'C'])
deck[deck.index("B")] = 'A' -> deck[0] = 'A' (deck = ['A', 'B', 'C'])
Array#index returns when it finds the first match.Now,
deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
-> deck[deck.index("B")], deck[deck.index("A")] = 'A', 'B'
-> deck[deck.index("B")] = 'A' -> deck[1] = 'A' (deck = ['A', 'A', 'C'])
-> deck[deck.index("A")] = 'B' -> deck[0] = 'B' (deck = ['B', 'A', 'C'])
Difference between += for Integers/Strings and For Arrays?
You see, names (variable names, like a
and b
) don't hold any values themselves. They simply point to a value. When you make an assignment
a = 5
then a
now points to value 5, regardless of what it pointed to previously. This is important.a = 'abcd'
b = a
Here both a
and b
point to the same string. But, when you do thisa += 'e'
It's actually translated toa = a + 'e'
# a = 'abcd' + 'e'
So, name a
is now bound to a new value, while b
keeps pointing to "abcd".a = [1,2,3,4]
b = a
a << 5
There's no assignment here, method <<
modifies existing array without replacing it. Because there's no replacement, both a
and b
still point to the same array and one can see the changes made to another. Ruby: Hash assignment with concurrent loops
I think you just need to add a little map
to my answer to your other similar question:
hash = Hash[quadrant.zip(array.each_slice(2).map { |a| @board[a.first][a.last] })]
Given a board like this:@board = [
['11', '12', ... '18'],
['21', '22', ... '28'],
...
['81', '82', ... '88']
]
the above construct gives me a hash
like this:{
"upper_left" => "77",
"upper_right" => "75",
"lower_left" => "57",
"lower_right" => "55"
}
and that seems to be what you're looking for. Ruby block taking array or multiple parameters
Ruby's block mechanics have a quirk to them, that is if you're iterating over something that contains arrays you can expand them out into different variables:
[ %w[ a b ], %w[ c d ] ].each do |a, b|
puts 'a=%s b=%s' % [ a, b ]
end
This pattern is very useful when using Hash#each
and you want to break out the key
and value
parts of the pair: each { |k,v| ... }
is very common in Ruby code.If your block takes more than one argument and the element being iterated is an array then it switches how the arguments are interpreted. You can always force-expand:
[ %w[ a b ], %w[ c d ] ].each do |(a, b)|
puts 'a=%s b=%s' % [ a, b ]
end
That's useful for cases where things are more complex:[ %w[ a b ], %w[ c d ] ].each_with_index do |(a, b), i|
puts 'a=%s b=%s @ %d' % [ a, b, i ]
end
Since in this case it's iterating over an array and another element that's tacked on, so each item is actually a tuple of the form %w[ a b ], 0
internally, which will be converted to an array if your block only accepts one argument.This is much the same principle you can use when defining variables:
a, b = %w[ a b ]
a
# => 'a'
b
# => 'b'
That actually assigns independent values to a
and b
. Contrast with:a, b = [ %w[ a b ] ]
a
# => [ 'a', 'b' ]
b
# => nil
I have a issue.. Appending
As written, you are unconditionally appending to x,y,z even after they hit your limit.... if each string contains 60 numbers I want it to append into the a string until there are no more numbers
You need to add a conditional around this code:
x << i if count == 1
y << i if count == 2
z << i if count == 3
so that it stops appending once it hits your limit.By the looks of the else block that does nothing, I think you were headed in that direction:
if x.length == 60
a << i if count == 1
a << i if count == 2
a << i if count == 3
else
x << i if count == 1
y << i if count == 2
z << i if count == 3
end
Even that, though, won't do exactly what you want. You'll want to check the string you are appending to to see if it has hit your limit yet.
I'd suggest refactoring to make it cleaner:
users.each do |i|
target_string = case count
when 1 then x
when 2 then y
when 3 then z
end
target_string = a if target_string.length == 60
target_string << i
if count == 3
count = 1
else
count += 1
end
end
Related Topics
How to Avoid Circular Creation of Associated Models in Factory_Girl
Clean Install Osx 10.9.1 Returns "Undefined Method 'Path2Class'" When Trying to Install Gems
Adding Bootstrap Icon to Button in Ruby on Rails
Why Am I Getting "Unable to Autoload Constant" with Rails and Grape
Functional Testing of a Restful Post in Ruby on Rails
How to Reference a Local Gem from a Ruby Script
Activemodel::Validations on Anonymous Class
How to Handle Omniauth Callbacks in Multiple Environments
How to Properly Manage The Rails Tmp Directory
Using Update_Columns in Rails 3
Strong Parameters with Nested Hash
Indent Multiline String in Erb
Why Does Including This Module Not Override a Dynamically-Generated Method