views:

71

answers:

4

I have a ruby hash:

VALS = { :one => "One", :two => "Two" }

and an Array:

array2 = ["hello", "world", "One"]

Question: How can I populate a new array1 so that it only pulls in any values in array2 that match exactly the values in VALS?

For example, I have tried: array2.each_with_index do |e,i| array1 << e if VALS[i] ~= e end

Along with other thing, and none work. Noob.

Thanks

+6  A: 

Using nested loops would be very slow if both collections are large. It's better to treat the contents as sets:

array1 = VALS.values & array2
print array1

Output:

One
Mark Byers
Dmytrii Nagirniak
hmmm... works without require 'set' too.. never would have thought!but how about if I want to get the i + 1th element of the array that matched for the ith element?
Eric
A: 

Here's an option:

hash = { :one => "One", :two => "Two" }
array = ["hello", "world", "One"]

p array.select { |i| hash.has_value? i }
# >> ["One"]
dylanfm
thanks! how would I select the i+1 values for each match?
Eric
A: 

brilliant! but whent I tried:

p array.select { |i| hash.has_value? i ? array[i+1] : "foo"}

I got an can't convert fixnum error. I must be missing something.

Eric
Please keep in mind that this is a question-and-answer site, not a discussion forum. You can't post a reply to another answer as an answer, because answers aren't ordered that way. If you want to add to the question, you can edit it. If you want to comment on an answer, you can use a comment.
Chuck
I think you are missing that select doesn't yield the index to the block, but rather the value.So in your expression "array[i+1]" you are saying "One" + 1 and then you'll end up with a TypeError: can't convert Fixnum into String.
Thorbjørn Hermansen
A: 

got it!

array.select do |i|
  if VALS.has_value? i
    result << array[array.index(i)+1]
  end
end
Eric