2016-10-10 1 views
0

Ich verwende Rails 4.2.7. Ich habe zwei Arrays (arr1 und arr2), die beide meine Modellobjekte enthalten. Gibt es eine Möglichkeit, eine Kreuzung auf beiden Arrays zu machen, wenn ein Objekt von arr1 ein Feld "myfield1" (welches eine Zahl ist) hat, das mit einem Objekt in arr2 übereinstimmt? Beide Arrays haben eindeutige Objektgruppen. Derzeit habe ichIn Rails, wie führe ich einen Schnittpunkt von zwei Arrays basierend auf einem Feld in jedem Objekt in den Arrays?

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 

aber das scheint mir als etwas ineffizient. Ich denke, es gibt einen einfacheren Weg, um die Ergebnisse zu bekommen, die ich brauche, aber ich bin nicht genug mit Ruby vertraut, um zu wissen, wie es geht.

+0

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

+0

Konvertieren jedes Arrays in einen Hash mit dem Feld als Schlüssel zB: 'hash1 = arr1.each_with_object ({}) {| x, hsh | hsh [x.field] = x}; hash2 = arr2.each_with_object ({}) {| x, hsh | hsh [x.field] = x} 'und tun' (hash1.keys & hash2.keys) .map {| x | hash1 [x] || hash2 [x]} ' – bjhaid

Antwort

0

Sie können eine Schnittmenge der Werte erstellen, um die gemeinsamen Werte zu finden, und dann Datensätze mit den gemeinsamen Werten auswählen.

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} 

ich in Ihrem Code bemerken, sind Sie nur Datensätze aus arr1 Speicherung ... wenn das dann das richtige Verhalten ist kann man meine Antwort vereinfachen

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

Ich bin nicht sicher, ob Ihre Lösung die Lösung in der Frage übertrifft, angesichts der Kosten von' Array # include? '. Konvertiere jedes Array in einen Hash mit dem Feld als Schlüssel und benutze '(hash1.keys & hash2.keys) .map {| x | hash1 [x] || hash2 [x]} 'wird besser funktionieren – bjhaid

+0

@bjhaid Ich mag Ihren Vorschlag und wenn Sie es aufschreiben, werde ich es abstimmen. Aber ich denke 'hash1 [x] || hash2 [x] 'wird immer nur' hash1 [x] 'zurückgeben, da es durch die Definition von iintersection immer existiert. Dieser Teil muss möglicherweise erneut analysiert werden. – SteveTurczyn

+0

Sie sind richtig, entweder 'hash1 [x]' oder 'hash2 [x]' sollte anstelle von 'hash1 [x] || genügen hash2 [x] 'abhängig von dem Objekt, an dem das OP interessiert ist – bjhaid

Verwandte Themen