2016-10-10 25 views
0

我正在使用Rails 4.2.7。我有兩個數組(arr1和arr2),都包含我的模型對象。如果arr1中的對象有一個匹配arr2中的對象的字段「myfield1」(這是一個數字),是否有辦法在兩個數組上執行交集?這兩個數組都將具有唯一的一組對象。目前,我有在Rails中,如何基於數組中每個對象中的字段執行兩個數組的相交?

arr1.each_with_index do |my_object, index| 
    arr2.each_with_index do |my_object2, index| 
     if my_object.myfield1 == my_object2.myfield1 
      results.push(my_object) 
     end 
    end 
end 

但這讓我覺得有點低效。我認爲有一種更簡單的方法可以獲得我需要的結果,但是在Ruby中我不夠精通,無法知道如何去做。

+0

http://ruby-doc.org/ core-1.9.3/Array.html#method-i-26 – bjhaid

+0

將每個數組轉換爲一個散列,並將字段作爲鍵。例如:'hash1 = arr1.each_with_object({}){| x,hsh | hsh [x.field] = x}; hash2 = arr2.each_with_object({}){| x,hsh | hsh [x.field] = x}'並做'(hash1.keys&hash2.keys).map {| x | hash1 [x] || hash2 [x]}' – bjhaid

回答

0

您可以構建這些值的交集以查找共同值,然後選擇具有共同值的記錄。

field_in_both = arr1.map(&:myfield1) & arr2.map(&:myfield1) 
intersection = arr1.select{|obj| field_in_both.include? obj.myfield1} + 
       arr2.select{|obj| field_in_both.include? obj.myfield1} 

我在你的代碼發現,你只是存儲從ARR1記錄......如果這是正確的行爲,你可以簡化我的回答

field_in_both = arr1.map(&:myfield1) & arr2.map(&:myfield1) 
intersection = arr1.select{|obj| field_in_both.include? obj.myfield1} 
+0

由於'Array#include?'的代價,我不確定你的解決方案會超越問題的解決方案。將每個數組轉換爲一個散列,並將字段作爲鍵並使用'(hash1.keys&hash2.keys).map {| x | hash1 [x] || hash2 [x]}'會表現更好 – bjhaid

+0

@bjhaid我喜歡你的建議,如果你把它寫出來,我會投票。但是我認爲'hash1 [x] || hash2 [x]'將總是隻返回'hash1 [x]',因爲根據iintersection的定義它將一直存在。這部分可能需要重新分析。 – SteveTurczyn

+0

你是正確的'hash1 [x]'或'hash2 [x]'應該足夠代替'hash1 [x] || hash2 [x]'取決於OP感興趣的對象 – bjhaid

相關問題