2010-11-26 15 views
25

Quiero ordenar una matriz en un orden particular dado en otra matriz.¿Cómo ordenar una matriz en Ruby en un orden particular?

EX: considerar una serie

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

Ahora desea ordenar serie 'a' en el orden de 'b', es decir

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

Así que la salida debe ser

two 
one 
three 

¿Alguna sugerencia?

+2

Como está, esta pregunta no tiene sentido. El ejemplo muestra dos matrices con los mismos valores exactos (solo en diferente orden). Si quieres iterar los elementos en 'a' en el orden que se encuentra en' b', bueno, itera 'b' y listo :-) Así que supongo que hay más condiciones, tal vez los elementos en las matrices no coinciden? ¿No es un "==" entre los objetos lo que necesitas sino un tipo diferente de igualdad? muestra algunos ejemplos más significativos. – tokland

Respuesta

45

Array # sort_by es lo que buscas.

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

versión más escalable en respuesta al comentario:

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

El más simple para matrices pequeñas, pero tenga en cuenta que esto es O (n^2) cuando el problema es O (n). – tokland

+0

@tokland Ok. Suministrado una versión más escalable. –

+0

exactamente, crea un mapeo auxiliar + sort_by. Probablemente lo escriba 'lookup = Hash [b.to_enum.with_index]', pero bueno, eso es solo un detalle. Por cierto, ¿viste mi comentario a la pregunta? ¿Recuerdas lo que el OP tenía en mente? – tokland

12

Si b incluye todos los elementos de a y si los elementos son únicos, entonces:

puts b & a 
+0

Si esa condición se cumple, 'b & a == b'. –

+1

@PanThomakos, puede incluir elementos y también otros. '% w {ameba bug bird dog horse shark} &% w {horse ameba shark} => [" ameba "," horse "," shark "]' – Nakilon

+1

Creo que está bien que esto funcione, pero aquí están mis reservas: 1. Usar & (establecer intersección) para ordenar matrices es engañoso. 2. El código es frágil. Si las listas tienen elementos duplicados o tienen el tamaño incorrecto, el código se rompe. Si la implementación de & cambia para que los elementos ya no estén clasificados, el código se rompe. –

8

Suponiendo a es que ser resuelto con respecto al orden de los elementos en b

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

Normalmente uso esto para ordenar los mensajes de error en ActiveRecord en el orden de aparición de los campos en el formulario.

+1

¿Por qué usar 'sort' cuando puedes usar' sort_by'? –

+0

Rendimiento. http://ruby-doc.org/core/classes/Enumerable.html#M003120 Echa un vistazo a la evaluación comparativa. – Chirantan

+2

Mi punto de referencia muestra 'N' sec para' sort', '0.07 N' sec para' sort_by' y '0.01 N' para' & '. – Nakilon

Cuestiones relacionadas