Question

I am trying to determine if the an element in one multi-dimensional array exists in another similarly structured array.

suspects = [['Rod', 100], ['Jane', 75], ['Freddy', 125]]
criminals = [['Bill', 75], ['Ted', 50], ['Rod', 75]]

The response I am looking for is either true or false. In the example above the response would be true because Rod exists in both arrays. The integer value has in the second tier array has no bearing.

How would I code such a test in typically Ruby-like succinctness?

Was it helpful?

Solution

suspects.any? do |suspect, _|
  criminals.any? do |criminal, _|
    suspect == criminal
  end
end

OTHER TIPS

Faster like this:

suspects.any? {|s,_| criminals.assoc(s)}

sepp2k beat me to it, but i have to submit just to show how close we were in implementation:


suspects.find do |suspect_name, _|
  criminals.find {|criminal_name, _| criminal_name == suspect_name}
 end 

I like his use of any?, but think the inner block should be inline :)

How about:

(suspect.size + criminal.size) > (suspect | criminals).size

Sample:

suspects = [['Rod', 100], ['Jane', 75], ['Freddy', 125]]
criminals = [['Bill', 75], ['Ted', 50], ['Rod', 75]]

guilty = (suspects.size + criminals.size) > (suspects | criminals).size
# Returns false. Since no common element was found in the merging.

criminals << ['Jane', 75]
guilty = (suspects.size + criminals.size) > (suspects | criminals).size
# Returns true. Since one element is common, merged array will be shorter by one.

I'm not necessarily recommending this, but anther one-line option (two if you count the require) could be this:

require 'set'
(suspects.map{|s| s[0]}.to_set & criminals.map{|c| c[0]}.to_set).size > 0

=> true

It builds arrays from the first element of each item then converts it to a Set. Set has the & (intersect) method and we look at the size of the result for our answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top