2010-11-26 7 views
25

Je veux trier un tableau dans l'ordre particulier donné dans un autre tableau.Comment faire pour trier un tableau dans Ruby à un ordre particulier?

EX: envisager un tableau

a=["one", "two", "three"] 
b=["two", "one", "three"] 

Maintenant, je veux trier tableau 'a' dans l'ordre de 'b', à savoir

a.each do |t| 
    # It should be in the order of 'b' 
    puts t 
end 

Ainsi, la sortie doit être

two 
one 
three 

Des suggestions?

+2

En l'état, cette question n'a aucun sens. L'exemple montre deux tableaux avec exactement les mêmes valeurs (seulement dans un ordre différent). Si vous voulez itérer les éléments dans 'a' dans l'ordre trouvé dans' b', bien, itérez 'b' et vous avez terminé :-) Donc je suppose qu'il y a plus de conditions, peut-être que les éléments des tableaux ne correspondent pas? n'est pas un "==" entre les objets ce dont vous avez besoin mais un type différent d'égalité? montrer des exemples plus significatifs. – tokland

Répondre

45

Array # sort_by est ce que vous recherchez.

a.sort_by do |element| 
    b.index(element) 
end 

Version plus évolutive en réponse à un commentaire:

a=["one", "two", "three"] 
b=["two", "one", "three"] 

lookup = {} 
b.each_with_index do |item, index| 
    lookup[item] = index 
end 

a.sort_by do |item| 
    lookup.fetch(item) 
end 
+1

Le plus simple pour les petits tableaux, mais notez que c'est O (n^2) lorsque le problème est O (n). – tokland

+0

@tokland Ok. Fourni une version plus évolutive. –

+0

exactement, créez un mappage auxiliaire + sort_by. Je l'écrirais probablement 'lookup = Hash [b.to_enum.with_index]', mais bon, c'est juste un détail. Btw, avez-vous vu mon commentaire à la question? vous souvenez-vous de ce que le PO avait en tête? – tokland

12

Si b comprend tous les éléments de a et si des éléments sont uniques, alors:

puts b & a 
+0

Si cette condition est remplie, alors 'b & a == b'. –

+1

@PanThomakos, Il peut inclure des éléments et en avoir d'autres. '% w {ameba bug oiseau cheval cheval requin} &% w {cheval ameba requin} => [" ameba "," cheval "," requin "]' – Nakilon

+1

Je pense que c'est cool que cela fonctionne, mais voici mes réserves: 1. L'utilisation de & (définir l'intersection) pour trier les tableaux est trompeuse. 2. Le code est fragile. Si les listes ont des éléments en double ou sont de la mauvaise taille, le code se brise. Si la mise en œuvre de & change de sorte que les éléments ne sont plus triés, le code rompt. –

8

En supposant a doit être trié par rapport à l'ordre des éléments dans b

sorted_a = 
a.sort do |e1, e2| 
    b.index(e1) <=> b.index(e2) 
end 

Je l'utilise normalement pour trier les messages d'erreur dans ActiveRecord dans l'ordre d'apparition des champs sur le formulaire.

+1

Pourquoi utiliser 'sort' quand vous pouvez utiliser' sort_by'? –

+0

Performance. http://ruby-doc.org/core/classes/Enumerable.html#M003120 Consultez l'analyse comparative. – Chirantan

+2

Mon benchmark montre 'N' sec pour' sort', '0.07 N' sec pour' sort_by' et '0.01 N' pour' & '. – Nakilon

Questions connexes