0

I have a hash that has some keys as an array like so:

foo = {[45, 121]=>:some_field}

How can I select :some_field where a foo key contains 45?

And secondary to that, if it finds a match, how do I retrieve the other elements in the same key?

2
  • 4
    Your hash is oddly backwards. Typically :some_field would be the key, and the value would be an array to which you append additional numbers. I can't say for certain that it you're using it incorrectly as there is absolutely no context, but an array=>symbol hash is not often as useful as symbol=>array. Commented Sep 6, 2012 at 14:55
  • How is the hash constructed? Can you change it for much more efficient lookup? Commented Sep 6, 2012 at 14:59

3 Answers 3

4

Although you can do this, it kind of defeats the purpose of using a hash since you will have to do a linear scan through the entire thing. It would be a lot better to have multiple hash keys for the same value since you can use the hash as an index then.

Example:

found = foo.find { |k, v| k.include?(n) }
found and found[1]

Keep in mind the performance of this will be terrible if you have large numbers of entries in the key and a large number of items in the hash since it will have to test against all keys and all values individually.

Sign up to request clarification or add additional context in comments.

1 Comment

Actually, I would be ok with re-processing foo such that 45 and 121 are unique keys and I just copy :some_field to each. How would I do this?
2
foo = {[45, 121]=>:some_field}
foo.detect{ |k,v| k.include? 45 }
#=> [[45, 121], :some_field]
foo.detect{ |k,v| k.include? 45 }.last
#=> :some_field

1 Comment

While this works, it is as bad as walking an array looking for the results.
1

I would suggest to reverse your hash if it's not one element only:

foo = {[45, 121]=>:some_field, [1, 45, 7] => :some_other_field}

bar = {}
foo.each do |k, v|
  k.each do |x|
    if bar.has_key?(x)
      bar[x] << [[k, v]]
    else
      bar[x] = [[k, v]]
    end
  end
end

p bar[45]

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.