簡體   English   中英

在復合數組中查找唯一元素

[英]Find a unique element in a compound array

我正在嘗試解決一個問題,該問題需要我在一個數組的數組中找到一個代表多城市飛行計划起點的機場代碼。 例如:給定數組[['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

我知道您在嘗試什么。 始發機場將是唯一包含在子數組的0索引中的機場,而不是任何子數組的1索引中包括的機場。

然而,在你的解決方案,你是比較2個陣列的每個組合(包括一個子陣列和本身,順便...),然后返回的索引list ,如果a[0] != b[1]對於子數組a永遠是正確a 這將返回太多結果,並且您將總是最終返回最后一個索引。 例如,第三個子數組的0索引'SEA'不等於0子數組的1索引'BWI',因此start_point現在等於3。

我不會為您完成所有工作:),但我建議您這樣做:在進行迭代時,請跟蹤哪個子數組的索引0等於另一個子數組的索引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

抱歉,我沒有足夠的時間來解釋我的代碼-但我認為沒有弄清楚發生了什么事就這么困難:)

這是工作示例

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

基於dwenzel的想法:

airports = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]

departures, arrivals = airports.transpose

first_departure_index = departures.index{|dep| !arrivals.include?(dep)}
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

如果您考慮了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

HTH

您可以這樣做:

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 (如在其他答案中所做的那樣)或Enumerable#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"]

包含所有出現不止一次的機場; 也就是說,所有“中間”機場。

trips = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]

arrivals = trips.map(&:last)

p trips.find{|fligth| ! arrivals.include? fligth[0] } #=> ["BOS", "SEA"]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM