2016-01-15 12 views
9

Ich versuche, ein Array mit einer Mischung aus Ints und Strings zu sortieren. Nehmen Sie zum Beispiel:Wie sortiere ich ein Array von Ints und Strings?

a = ["a", "b", 5, "c", 4, "d", "a1", "a12", 3, 13, 2, "13a", "12a"] 

Ich habe versucht:

a.sort do |x, y| 
    if x.class == y.class 
    x <=> y 
    else 
    x.class.to_s <=> y.class.to_s 
    end 
end 

Welche zurück:

[2, 3, 4, 5, 13, "12a", "13a", "a", "a1", "a12", "b", "c", "d"] 

Das Resultat, das ich will, ist:

[2, 3, 4, 5, "12a", 13, "13a", "a", "a1", "a12", "b", "c", "d"] 
+0

Kann es mehr als eine Zahl in Ihren Strings, z '" a1b2c3 "'? – Stefan

+0

Was ist richtig? '[" a1 "," a12 "," a2 "]' oder '[" a1 "," a2 "," a12 "]'? – Stefan

+0

@Stefan Möglich, mehr als eine Zahl in einer Zeichenfolge zu haben. Letzteres '[" a1 "," a2 "," a12 "]' –

Antwort

11
a.sort_by { |x| [(x.to_s.match(/^\d+/) ? x.to_i : 1.0/0), x.to_s] } 

Die Idee besteht darin, zuerst nach dem numerischen Wert und dann nach dem Zeichenfolgenwert zu sortieren. Wenn die Zeichenfolge nicht mit einem numerischen Wert beginnt, berücksichtigen Sie den numerischen Wert mit Nachdruck als unendlich.


EDIT: Wie OP hat klargestellt, dass er will die führende numerischen Wert prüfen, nicht nur, aber alles, was folgen, können wir die gleiche Idee verwenden, nur dieses Mal müssen wir es auf jeden einzelnen gelten numerische und nicht-numerische Einheit in der Zeichenfolge:

a.sort_by do |x| 
    x.to_s.split(/(\D+)/).map do |y| 
    [(y.match(/\d/) ? y.to_i : 1.0/0), y] 
    end 
end 
+1

Eine '0' im Array würde zwischen' "13a" "und" " – Stefan

+0

@Stefan, aktualisiert werden. – ndn

+0

Das ist besser, aber es sortiert nicht '[" a13 "," a2 "]' richtig. – Stefan

Verwandte Themen