2

This is a rock paper scissors game. From irb, game.class says it's an array. I hope to find the name of the person who won the game (in this case Player2).

game = [["Player1", "P"], ["Player2", "S"]]

The approach that comes to mind is to return a Hash with the name values split up. Then search that hash via the value to get the player name.

h = Hash.new(0)
game.collect do |f|
  h[f] = f[1]
end
h
#=> {["Player1", "P"]=>"P", ["Player2", "S"]=>"S"}

This is close but no cigar. I want

{"Player1" => "P", "Player2" => "S"}

I tried again with inject method:

game.flatten.inject({}) do |player, tactic| 
  player[tactic] = tactic  
  player 
end
#=> {"Player1"=>"Player1", "P"=>"P", "Player2"=>"Player2", "S"=>"S"}

This did not work:

Hash[game.map {|i| [i(0), i(1)] }]
#=> NoMethodError: undefined method `i' for main:Object

I would appreciate some pointers to something that will help me understand.

1

4 Answers 4

3

You can simply do this too.

game = [["Player1", "P"], ["Player2", "S"]]
#=> [["Player1", "P"], ["Player2", "S"]]
Hash[game]
#=> {"Player1"=>"P", "Player2"=>"S"}
Sign up to request clarification or add additional context in comments.

4 Comments

holy cow! can you explain what happened there?
I'll play around with this more later. Thank you
Thanks that really simplifies the thinking.
I think I would have ended up in daisy chain hell even though inject is perfectly fine below. I'll select this as the answer as it got me thinking straight about hashes, although both are right
2

Use:

game.inject({}){ |h, k| h[k[0]] = k[1]; h }

3 Comments

that works too! I have to figure out what that h[k[0]] is doing.
I think I see, it's actually a nested element call to the first pair item then link to the second item of the same pair. Is that a fair translation?
Hmm....Oh for each element in game it builds the next section. Man I'm glad I got to sleep. Thank you
2

Using each_with_object means you don't need to have two statements in the block, like in xdazz's answer

game.each_with_object({}){ |h, k| h[k[0]] = k[1] }

You can make this even more readable by destructuring the second block parameter

game.each_with_object({}){ |hash, (name, tactic)| hash[name] = tactic }

1 Comment

That's pretty interesting, thank you. It has a nice readability to it
0

You can use Ruby's built in Array#to_h method for this:

game.to_h
#=> {"Player1"=>"P", "Player2"=>"S"}

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.