2009-07-28 16 views
68

Ich habe zwei Arrays von Aufgaben - erstellt und zugewiesen. Ich möchte alle zugewiesenen Aufgaben aus dem Array der erstellten Aufgaben entfernen. Hier ist meine Arbeit, aber chaotisch, Code:Subtrahieren eines Array von einem anderen in Ruby

@assigned_tasks = @user.assigned_tasks 
    @created_tasks = @user.created_tasks 

    #Do not show created tasks assigned to self 
    @created_not_doing_tasks = Array.new 
    @created_tasks.each do |task| 
     unless @assigned_tasks.include?(task) 
      @created_not_doing_tasks << task 
     end 
    end 

Ich bin sicher, es gibt einen besseren Weg. Was ist es? Dank :-)

+0

Ich wette unter der Haube die Antwort ist nur tun, was Sie dort codiert haben. – baash05

Antwort

147

können Sie Arrays in Ruby subtrahieren:

[1,2,3,4,5] - [1,3,4] #=> [2,5] 

ary - other_ary → new_ary Array Difference

Gibt ein neues Array, das eine Kopie des Original-Array ist, das Entfernen alle Elemente, die auch in other_ary erscheinen. Die Reihenfolge wird vom Originalarray beibehalten.

Es vergleicht Elemente mit ihren Hash und eql? Methoden für die Effizienz.

[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]

Wenn Sie Set-ähnliches Verhalten benötigen, finden Sie in der Bibliothek Klasse Set.

Siehe die Array Dokumentation.

+2

Arg. Großer Gesichts-Palm-Moment für mich. Aus irgendeinem Grund dachte ich, das würde nicht mit Objekten funktionieren. Hat gut funktioniert - danke! – doctororange

+1

np, es passiert :) – hobodave

+25

vorsichtig mit diesem, testen Sie es zuerst in IRB, zum Beispiel: [5, 5, 5, 5] - [5, 5] = [] ... die Subtraktion entfernt die einzigartigen Elemente in der Array. – hagope

4

Die obige Lösung

a - b 

löscht alle Instanzen von Elementen in Array von Array ba.

[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ] 

In einigen Fällen mögen Sie das Ergebnis [1, 2, 3, 3, 5] sein. Das heißt, Sie möchten nicht alle Duplikate löschen, sondern nur die Elemente einzeln.

Sie können dies erreichen, indem

class Array 
    def delete_elements_in(ary) 
    ary.each do |x| 
     if index = index(x) 
     delete_at(index) 
     end 
    end 
end 

Test

irb(main):198:0> a = [ 1, 1, 2, 2, 3, 3, 4, 5 ] 
=> [1, 1, 2, 2, 3, 3, 4, 5] 
irb(main):199:0> b = [ 1, 2, 4 ] 
=> [1, 2, 4] 
irb(main):200:0> a.delete_elements_in(b) 
=> [1, 2, 4] 
irb(main):201:0> a 
=> [1, 2, 3, 3, 5] 

Der Code funktioniert auch, wenn die beiden Arrays nicht sortiert werden. Im Beispiel sind die Arrays sortiert, dies ist jedoch nicht erforderlich.

Verwandte Themen