2016-05-22 16 views
1

Ich mache eine Flugbuchungsanwendung in Rails und habe erfolgreich Daten von Flügen als Arrays aufgelistet.So entfernen Sie Duplikate in einem Array von Arrays Ruby

Allerdings habe ich ein Problem mit Duplikaten. Ich habe eine select_tag (gebraucht: Termine, options_for_select (@dates), die funktioniert, aber ich habe alle diese doppelte Termine bekam

Heres den Code für @dates

@dates=Flight.all.map do |a| 
    dates=[] 
    unless dates.any? && dates.last[0]==a.flight_date_formatted 
    dates<<[a.flight_date_formatted, a.id] 
    end 
end 

Dies gibt ein.. Array von Arrays des Typs ["22/5/2016", 1]. Ich kann unique wegen des zweiten Elements nicht verwenden, in dem die id immer anders ist.

In dem Code versuche ich um auf das letzte/erste Element des Arrays zuzugreifen und sein [0] Element zu erhalten, was "22/5/2016" wäre und wenn es gleich dem aktuellen Datum ist, dann überspringe diese Iteration funktioniert nicht so, wie ich es erwarte.

Es gibt 7 Flüge und nur 3 verschiedene Daten, so dass es nicht schwer ist, mindestens einen anderen zu fangen.

Wie kann ich die doppelten Datensätze filtern?

Antwort

2

die Flüge direkt aus der Datenbank eindeutig durch Datum abzufragen und bereits sortiert, können Sie Active dies tun verwenden:

today = DateTime.now.to_date 
@flights = Flight.select("DISTINCT flight_date, *").where("flight_date < ?", today).group(:flight_date).order("flight_date") 

Dabei die DISTINCT und group verwendet werden, um die Flüge einzigartig von flight_date zu machen. Die order wird verwendet, um die Ergebnisse zu sortieren; Wenn Sie sie in umgekehrter Reihenfolge sortieren möchten, verwenden Sie order("flight_date DESC"). Die where sagt, nur die Flüge, die ein Flugdatum vor heute haben, abzurufen. Jedes dieser Elemente kann geändert werden, um auch für ähnliche Abfragen geeignet zu sein.

Wenn bereits Duplikate aus der Datenbank abgerufen wurden, können Sie sie im Speicher mit der Ruby-Standardbibliothek Array#unique mit einem Block sortieren. Versuchen Sie dies:

@flights = Flight.all.unique {|a,b| a[0] <=> b[0] } 

Dies wird ein Array zurückgeben, das durch das erste Element eindeutig ist.

Um den Filtercode zu korrigieren, müssen Sie nur den Wert aus dem Block zurückgeben. Dies sollte den richtigen Wert aus dem map Block zurück:

@dates=Flight.all.map do |a| 
    dates=[] 
    unless dates.any? && dates.last[0]==a.flight_date_formatted 
    dates<<[a.flight_date_formatted, a.id] 
    end 
    dates 
end 

Die „kurze“ Art und Weise Datensätze herauszufiltern, ist mit Array#select, die Sie wie folgt verwenden können:

today = DateTime.now.strftime("%-d/%-m/%Y") 
@flights = @flights.select {|flight| flight[0] != today } 
+0

danke, sehr elegante Antwort . Ich habe am Ende eine Hilfsmethode auf dem Controller verwendet. Ihr Weg wäre, die Flüge mit einzigartigen Daten zu bekommen, dann würde ich meinen Datumscode darüber laufen lassen, wenn ich das richtig verstanden hätte. –

+0

@nathaks Ich habe meine Antwort aktualisiert, um die Datensätze aus der Datenbank bereits sortiert und eindeutig abzurufen. Das ist eigentlich besser, als dies im Speicher zu tun. In Bezug auf Ihre Kommentarfrage können diese zusammen verwendet werden. Sie können auch unabhängig voneinander verwendet werden. Es hängt nur davon ab, wie Sie es in Ihrer Anwendung benötigen. Die Datenbanklösung sollte alle auf einmal sortieren und filtern. Ich habe die Beschreibungen aktualisiert, um ein wenig klarer zu sein. –

Verwandte Themen