Найти уникальный элемент в составном массиве
Я пытаюсь решить проблему, когда мне нужно найти код аэропорта в массиве массивов, который представляет собой отправную точку многолетнего плана полета.
Например: для массива [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']], где первый индексом каждого вспомогательного массива является
выездной аэропорт, а второй - аэропорт назначения, мне нужно найти индексный пункт, откуда начинается полет, в этом случае метод вернет 1, чтобы представлять ['BOS', 'SEA'].
Этот код не работает и всегда возвращает последний элемент в массиве
def find_start_point(list)
start_point = nil
list.each do |a|
list.each do |b|
if a[0] != b[1]
start_point = list.index(a)
end
end
end
start_point
end
Ответы
Ответ 1
Я вижу, что вы пытаетесь. Исходный аэропорт будет единственным, включенным в индекс 0 вспомогательного массива, но не одним индексом любого дополнительного массива.
Однако в вашем решении вы сравниваете каждую комбинацию из двух подматриц (включая вспомогательный массив и сам, кстати...), а затем возвращаем индекс list
, если a[0] != b[1]
когда-либо true для вспомогательного массива a
. Это возвращает слишком много результатов, и вы всегда будете возвращать последний индекс. Например, "SEA", индекс 0 третьего вспомогательного массива, не соответствует "BWI", 1 индексу 0-массива 0, поэтому ваш start_point
теперь равен 3.
Я не буду делать всю вашу работу за вас:), но позвольте мне предложить следующее: когда вы проходите через свои итерации, следите за тем, какой индекс вспомогательных массивов 0 когда-либо равен другому индексу sub-массива 1. Ваш ответ будет единственным, не включенным в этот список.
Изменить: Продолжайте работать по моему предложению о хорошей практике, но здесь действительно быстрое и короткое решение:
def find_start_point(list)
list.each_with_index do |sub, idx|
return idx if list.flatten.count(sub[0]) == 1
end
end
Это работает, возвращая индекс вспомогательного массива с индексом 0, где нет других вхождений этого аэропорта (путем сглаживания всего массива и использования #count
)
Ответ 2
Извините, у меня недостаточно времени, чтобы объяснить мой код, - но я думаю, что нет ничего сложного, чтобы не понять, что происходит:)
вот рабочий пример
def find_start_point(list)
start = []
finish = []
list.each do |l|
start.push(l[0])
finish.push(l[1])
end
start.each do |st|
if !finish.include? st
return start.index(st)
end
end
end
Ответ 3
Основываясь на идее двензеля:
airports = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]
departures, arrivals = airports.transpose
first_departure_index = departures.index{|dep| !arrivals.include?(dep)}
Ответ 4
def find_start(arr)
flat = arr.flatten
first, second = flat.reject { |val| flat.count(val) > 1}
start_city = if flat.index(first) % 2 == 0 #if index of first is even
first
else
second
end
arr.find { |pair| pair[0] == start_city }
end
Ответ 5
Если вы думаете с учетом синтаксиса Ruby, просто возьмите транспонирование и выведете всех прибывших из вылетов.
def flight_origin(arr)
plan = arr.transpose
plan[0].index((plan[0] - plan[1])[0])
end
flight_origin([['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]) # => 1
НТН
Ответ 6
Вы можете сделать это:
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"
Это можно было бы записать с помощью Array # transpose (как это было сделано в других ответах) или Переменная # zip с:
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"]
Моей главной причиной для ответа, однако, является создание плагина для метода Array#difference
, который я хотел бы увидеть в будущей версии Ruby. Он определен здесь.
С его помощью мы можем написать:
airports = legs.flatten
#=> ["LAX", "BWI", "BOS", "SEA", "HNL", "LAX", "SEA", "HNL"]
(legs.map(&:first) - airports.difference(airports.uniq)).first
#=> "BOS"
Обратите внимание, что:
airports.difference(airports.uniq)
#=> ["LAX", "SEA", "HNL"]
содержит все аэропорты, которые появляются более одного раза в ногах; то есть все "промежуточные" аэропорты.
Ответ 7
trips = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]
arrivals = trips.map(&:last)
p trips.find{|fligth| ! arrivals.include? fligth[0] } #=> ["BOS", "SEA"]