2011-10-11 2 views
15

Disons que j'ai un tableau non trié de 1 à 10, comme indiqué ci-dessous ...Trie un tableau de chaînes par leurs valeurs Integer

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

Si j'utilise la méthode de tri sur ce tableau, il renvoie cette ...

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

Comme vous pouvez le voir, le 10 apparaît avant le 2, ce qui est incorrect. Comment puis-je trier ces chiffres de sorte que 10 apparaisse correctement?

EDIT: Bonjour les gars, merci à tous pour vos réponses. Je devrais expliquer un peu mieux mon problème. Le tableau dont j'ai besoin trié est pour une liste de prix e-commerce. Le tableau apparaît donc comme suit ...

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

Les chaînes ne peuvent donc pas être converties en entiers. J'aurais dû mettre cela quand j'ai écrit la question. Je ne pensais pas qu'il y aurait beaucoup de différence dans le correctif. Mon erreur, je m'excuse d'avoir fait cette supposition! Comment puis-je trier ce tableau? Merci!

+0

Je pense que cette question a déjà été répondu: http://stackoverflow.com/questions/1955646/sort-strings-and-numbers-in-ruby/1964686#1964686 –

+0

Juste posté une réponse à votre mise à jour question – apneadiving

+0

Je vous suggère de poster une nouvelle question avec une description mise à jour, car toutes les réponses sont basées sur une mauvaise description. –

Répondre

43

Je jetterai une autre méthode là-bas puisqu'il chemin est le plus court que je peux penser à

a.sort_by(&:to_i) 
+0

Ceci est équivalent à la réponse de bricker, donc son commentaire sur le nombre de fois 'to_i' est appelé par rapport à la solution de Matt s'applique ici aussi. –

+0

Cela gère également la version modifiée de la question. –

+0

Qu'est-ce que '&:'? C'est une nouvelle syntaxe pour moi. – nipponese

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

Utilisez Enumerable # sort_by à la place – tokland

+0

Pourquoi? La méthode de tri fonctionne parfaitement, j'aimerais savoir pourquoi vous recommandez sort_by. – bricker

+7

Par définition xs.sort {| a, b | a.method <=> b.method} est totalement équivalent à xs.sort_by (&: méthode).Pourquoi utiliser tri lorsque vous avez un intégré plus court exactement conçu pour cette tâche? Si cela ne suffit pas, il y a aussi des raisons de performance, c & p des docs: "A partir de Ruby 1.8, la méthode Enumerable # sort_by implémente une Transformation Schwartzienne intégrée, utile lorsque le calcul ou la comparaison de clés est coûteux." – tokland

0

Le moyen le moins cher serait de remplir à zéro et de faire tous les chiffres à 2 chiffres.

+3

Bon marché et le meilleur moyen est de les trier comme des entiers au lieu de chaînes. – bricker

1

La raison de ce comportement est que vous disposez d'un tableau de chaînes et que le tri appliqué est basé sur une chaîne. Pour obtenir le tri correct, numérique, vous devez convertir les chaînes en nombres ou simplement les conserver en tant que nombres en premier lieu. Y at-il une raison que votre tableau est d'être renseigné avec des chaînes comme ceci:

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

Plutôt que de tels chiffres:

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

?

+0

S'il vous plaît voir mon édition, merci – tob88

6

Si vous convertissez toutes les chaînes en entiers à l'avance, il devrait fonctionner comme prévu:

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

Peu importe vraiment pour un si petit tableau, mais votre méthode serait plus rapide que le mien pour les grands tableaux, en appelant to_i seulement la moitié autant de fois. +1 – bricker

+1

@bricker La méthode de Matt utilise également plus de mémoire car elle crée un nouveau tableau avec 'map' que votre méthode ne fait pas. (Vous pouvez utiliser la carte in-situ 'map!', Mais cela n'est pas toujours une option viable dans votre code) –

+0

Bon point @WizardofOgz +1 – bricker

8

comme l'indique votre question: mise à jour

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

même geekier:

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

Ouais! Points bonus pour être geek! :) – Thom

Questions connexes