2016-04-15 9 views
-3

Ich möchte ein Array von Hashes, in denen jeder Hash hat zwei Attribute created_time und updated_time. Und der Wert dieser Attribute kann entweder ein Datenstring oder Nil sein. Ich will es nach created_time (ASC) zuerst und updated_time (ASC) sortieren. Ich versuchte mit sort_by Methode und ich konnte nicht die Bedingung für mehrere Schlüssel wie sort-Methode in this discussion vorgeschlagen vorschlagen.Ruby sort_by mehrere Felder, die Nullwerte enthalten können

Die beiden Attribute created_time und updated_time sollten mit Nullwerten zuletzt

nehme an, wenn das Array

[ 
{"created_time" => nil, "updated_time" => "2016-04-10"}, 
{"created_time" => nil, "updated_time" => "2016-04-09"}, 
{"created_time" => "2016-04-15", "updated_time" => nil} 
] 

Ich möchte das Ergebnis als

[ 
{"created_time"=>"2016-04-15", "updated_time"=>nil}, 
{"created_time"=>nil, "updated_time"=>"2016-04-09"}, 
{"created_time"=>nil, "updated_time"=>"2016-04-10"} 
] 

aufsteigend sortiert werden Was machen?

+2

, wenn Sie versucht haben, etwas haben kann, ist es hier posten, wenn es ein Problem ist, kann jemand Identifizieren Sie es. sag nicht, dass du es versucht hast und nicht funktioniert hast. zeig was du probiert hast und frage warum es nicht funktioniert hat oder wo du feststeckst! – Ccr

+1

Frage nicht vollständig angegeben. Wo möchten Sie die Elemente mit "Null" -Werten innerhalb der sortierten Liste platzieren? – sawa

+0

@sawa Ich möchte die Nullwerte an das Ende der sortierten Liste schieben – Magesh

Antwort

0

arr Angenommen ist ein Array von Hashes {"created_time"=>ct, "updated_time"=>ut}, wo ct (ut) entweder ein Datestring mit fomat "yyyy-mm-dd" oder nil. Lassen Sie far_away_time eine Datumsfolge sein, die garantiert später als jeder Datenstring-Wert ct oder ut ist. Zum Beispiel: far_away_time = "3000-01-01". Dann können Sie mit Enumerable #sort_by wie folgt sortieren:

arr.sort_by do |h| 
    ct, ut = h.values 
    case [ct.nil?, ut.nil?] 
    when [true, true] then [far_away_time, far_away_time, far_away_time] 
    when [true, false] then [far_away_time, far_away_time, ut] 
    when [false, true] then [far_away_time, ct, far_away_time] 
    else [ct, ut, ""] 
    end 
end 

Da die datestrings im ISO 8601-Format sind, gibt es keine Notwendigkeit, sie zu konvertieren Date Objekte (das heißt die Saiten selbst sortiert werden können). Zum Beispiel "2016-03-12" < "2016-03-13" #=> true. Anweisungen zur Anordnung der Arrays finden Sie im Dokument Array#<=>.

Ich Sortieranlage, um eine Drei-Element-Array sein, dass der Hashes {"created_time"=>"2016-01-01", "updated_time"=>nil}, {"created_time"=>nil, "updated_time"=>"2016-01-01"} und {"created_time"=>nil, "updated_time"=>nil} bestellt werden als I aufgeführt habe sie (und am Ende des sortierten Array platziert).

0

Sorry für den Mangel an Klarheit in der Frage. Ich wollte nur ein Array von Hashes mit zwei Schlüsseln in aufsteigender Reihenfolge sortieren, die Null values.And ich den Weg gefunden,

 def date_time datestring 
     DateTime.parse(datestring) 
    end 

    result = array_to_sort.sort do |a,b| 
    (a["created_time"] && b["created_time"] && a["updated_time"] && b["updated_time"]) ? [ date_time(a["created_time"]), date_time(a["updated_time"])] <=> [ date_time(b["created_time"]), date_time(b["updated_time"])] : [ a["created_time"] && b["created_time"] ? date_time(a["created_time"]) : a["created_time"] ? -1 : 1, a["updated_time"] && b["updated_time"] ? date_time(a["updated_time"]) : a["updated_time"] ? -1 : 1] <=> [ a["created_time"] && b["created_time"] ? date_time(b["created_time"]) : b["created_time"] ? -1 : 1, a["updated_time"] && b["updated_time"] ? date_time(b["updated_time"]) : b["updated_time"] ? -1 : 1] 
    end 
Verwandte Themen