2011-10-11 24 views
15

Diciamo che ho un allineamento non differenziati da 1 a 10, come mostrato di seguito ...ordinare un array di stringhe per la loro valori interi

a = ["3", "5", "8", "4", "1", "2", "9", "10", "7", "6"] 

Se uso il metodo di ordinamento in questo array, restituisce questo ...

a.sort = ["1", "10", "2", "3", "4", "5", "6", "7", "8", "9"] 

Come si può vedere, il 10, appare prima del 2, che non è corretto. Come posso ordinare questi numeri in modo che 10 appaia correttamente?

EDIT: Ciao ragazzi, grazie a tutti per le vostre risposte. Dovrei spiegare un po 'meglio il mio problema. L'array che ho bisogno di ordinare è per un listino prezzi di e-commerce. Quindi la matrice appare come segue ...

a = ["0-10", "11-20", "21-30", "31-40" etc.] 

Quindi le stringhe non possono essere convertiti in numeri interi. Avrei dovuto metterlo quando ho scritto la domanda. Non pensavo che ci sarebbe stata molta differenza nella correzione. Errore mio, mi scuso per aver fatto questa supposizione! Come posso ordinare questo array? Grazie!

+0

Penso che questa questione è già stata risolta: http://stackoverflow.com/questions/1955646/sort-strings-and-numbers-in-ruby/1964686#1964686 –

+0

appena pubblicato una risposta alla tua aggiornata domanda – apneadiving

+0

Ti suggerisco di pubblicare una nuova domanda con la descrizione aggiornata, dal momento che tutte le risposte sono basate sulla descrizione errata. –

risposta

43

mi butto un altro metodo là fuori dal momento che è la via più breve che posso pensare

a.sort_by(&:to_i) 
+0

Questo è equivalente alla risposta di Bricker, quindi il suo commento sul numero di volte "to_i' è chiamato rispetto alla soluzione di Matt anche qui. –

+0

Questo gestisce anche la versione modificata della domanda. –

+0

Cosa significa '&:'? Questa è una nuova sintassi per me. – nipponese

6
a.sort { |a,b| a.to_i <=> b.to_i } 
+3

usa Num. Enumerabile invece invece – tokland

+0

Perché? Il metodo di ordinamento funziona perfettamente, mi piacerebbe sapere perché si consiglia sort_by. – bricker

+7

Per definizione xs.sort {| a, b | a.method <=> b.method} è totalmente equivalente a xs.sort_by (&: method).Perché utilizzare l'ordinamento quando si dispone di un built-in più breve progettato esattamente per questa attività? Se ciò non è sufficiente, ci sono anche ragioni di prestazione, c & p dai documenti: "A partire da Ruby 1.8, il metodo Enumerable # sort_by implementa una Trasformata di Schwartzian incorporata, utile quando il calcolo o il confronto delle chiavi è costoso." – tokland

0

Il modo economico sarebbe azzerare il riempimento a sinistra e rendere tutti i numeri a 2 cifre.

+3

Economico e il modo migliore è ordinarli come numeri interi anziché stringhe. – bricker

1

Il motivo di questo comportamento è che si dispone di un array di stringhe e che l'ordinamento applicato è basato su stringhe. Per ottenere l'ordinamento numerico corretto, devi convertire le stringhe in numeri o semplicemente tenerle come numeri in primo luogo. C'è una ragione per cui l'array è di essere popolare con le stringhe come questo:

a = ["3", "5", "8", "4", "1", "2", "9", "10", "7", "6"] 

Invece di numeri come questo:

a = [3, 5, 8, 4, 1, 2, 9, 1, 7, 6] 

?

+0

Per favore vedi la mia modifica, grazie – tob88

6

Se si converte tutte le stringhe di numeri interi in anticipo, dovrebbe funzionare come previsto:

a.map(&:to_i).sort 
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
+0

Non ha importanza per un array così piccolo, ma il tuo metodo sarebbe più veloce del mio per array di grandi dimensioni, chiamando to_i solo la metà delle volte. +1 – bricker

+1

@bricker Il metodo di Matt usa anche più memoria poiché crea un nuovo array con 'map' che il tuo metodo non usa. (Potresti usare la mappa locale 'map!', Ma potrebbe non essere sempre un'opzione valida nel tuo codice) –

+0

Buon punto @WizardofOgz +1 – bricker

8

Man mano che i aggiornato stati domanda:

array.sort_by {|elt| ary = elt.split("-").map(&:to_i); ary[0] + ary[1]} 

anche geekier:

array.sort_by {|elt| ary = elt.split("-").map(&:to_i).inject(&:+)} 
+2

Sì! Punti bonus per essere geek! :) – Thom

Problemi correlati