I am trying to solve a problem where I need to find the airport code in an array of arrays of that represents the starting point of a multi-city flight plan. For example: Given
You could do this:
legs = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]
airports = legs.flatten
#=> ["LAX", "BWI", "BOS", "SEA", "HNL", "LAX", "SEA", "HNL"]
legs.map(&:first).find { |ap| airports.count(ap) == 1 }
#=> "BOS"
This could instead be written using Array#transpose (as has been done in other answers) or Enumerable#zip since:
legs.map(&:first)
#=> ["LAX", "BOS", "HNL", "SEA"]
legs.transpose.first
#=> ["LAX", "BOS", "HNL", "SEA"]
legs.first.zip(*legs[1..-1]).first
#=> ["LAX", "BOS", "HNL", "SEA"]
My main reason for answering, however, is to make a plug for the method Array#difference
, which I'd like to see in some future Ruby version. It is defined here.
With it, we can write:
airports = legs.flatten
#=> ["LAX", "BWI", "BOS", "SEA", "HNL", "LAX", "SEA", "HNL"]
(legs.map(&:first) - airports.difference(airports.uniq)).first
#=> "BOS"
Note that:
airports.difference(airports.uniq)
#=> ["LAX", "SEA", "HNL"]
contains all airports that appear more than once in the legs; that is, all all the "intermediate" airports.