Reputation: 15329
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?
Upvotes: 0
Views: 172
Reputation: 9225
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]
Upvotes: 1
Reputation: 211600
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.
Upvotes: 4
Reputation: 83680
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
Upvotes: 2