1

This may be very simple, but I don't know all of Ruby's array functions.

If I have a given array like:

values = [["a", 1], ["b", 3], ["c", 7], ... etc ]

I would like two functions:

  • A function that, when I give it "b", gives me 3.
  • The other way around, a function that when I give it 3, gives me "b".

There must be an easy way?

1
  • 2
    When asking for code, it's really important to show what you've tried, and describe why it doesn't do what you want. See #3 in the "On-topic" FAQ. As is, because you haven't done that, your question is technically off-topic, so you might want to fix that right away. Commented Jun 24, 2014 at 21:17

6 Answers 6

3
Hash[values]["b"] # => 3
Hash[values.map(&:reverse)][3] # => "b"
Sign up to request clarification or add additional context in comments.

Comments

2

My first question is: Does this have to be an array? Hash is designed for this and has key / value lookup built-in.

You can create a Hash from an array by doing:

hash = Hash[values]

Then use hash["a"] # => 1

For the reverse, do: hash.key(1) # => "a"

3 Comments

You can create a hash from an array, as long as the array contains an even number of elements. Odd numbered elements are treated as the keys, and even numbered elements are treated as the values.
@theTinMan Totally true. This assumption was based on the OP's example.
Well, the OP didn't know that it's possible to create a hash from an array, so the stipulation that the array has to be an even number of elements was probably also unknown.
2

The first is easy to achieve, by converting your array to a Hash with:

value_hash = Hash[values]

And access this with:

value_hash['b'] # => 3

For the other way around I would first like to know if you are sure that is is a unique request? So are both 'a','b','c',... and 1,3,7... etc. unique?

Comments

1
hash = array.to_h => Converts your array to a hash
hash[key] = value => Get the value associated with the key
hash.invert[key] = value => This method inverts your hash and you can select values

1 Comment

Thanks, it was for options_for_select, but now I realise this can take a hash as well, there is no need for the double array.
1

Yeah a hash is the answer, if you don't have duplicate keys of course. Otherwise you can use Array#assoc#rassoc which searches an array of arrays matching the first and last elements respectively:

ary =  [["A", 1], ["B", 2], ["C", 3], ["D", 4], ["E", 5], ["F", 6], ["G", 6]]
ary.assoc('A') => ["A", 1]
ary.rassoc('3') => ["C", 3]

Note: these methods return the first matching array, not all of them.

See more at http://www.ruby-doc.org/core-2.1.2/Array.html

Comments

0

I see no point in creating a hash to locate a single value. Why not the simple, direct approach?

values = [["a", 1], ["b", 3], ["c", 7]]

values.find { |l,n| l=='b' }.last  #=>  3
values.find { |l,n| n==3   }.first #=> "b"

Of course, neither of these deal with multiple values.

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.