2010-05-07 9 views
9

¿Cómo se puede hacer de la manera más sencilla para escribir (o tal vez hay algo incorporado en haskell) función que toma como argumentos lista de tuplas (String, Int) e Int x y devolver top x tuplas como lista de acuerdo a x valorhaskell sorting

Me pregunto si es posible escribir una función que también tome 3 argumentos, que es el nombre de (o índice) de archivado en tupla según la clasificación que se tiene que hacer.

¿Cuáles son las mejores soluciones para que sea bastante genérico?

+0

Sé que su pregunta es probablemente más por su propia curiosidad, pero ¿qué hace con los datos? ¿Es realmente una lista ordenada con la que quieres terminar? Ya no estamos barajando elementos en matrices de bajo nivel en C country y haskell te brinda fácil acceso a un zoológico completo de tipos de datos interesantes que probablemente sean más apropiados para hacer lo que sea que estés haciendo con el "ordenado" datos. – jberryman

+0

La razón es que estoy aprendiendo y quiero saber cuáles son las posibilidades, y la función de ordenar es la que todos entienden, por lo que la explicación es más fácil. Por supuesto, sé de tipos incrustados, todavía estoy aprendiendo, gracias – gruber

Respuesta

22
take x $ sortBy (compare `on` fst) [("asd", 1), ...] 

take x da los primeros x artículos de la lista ordenada. sortBy ordena la lista dada como segundo argumento utilizando la función de clasificación dada como primer argumento. (compare `on` fst) compara los primeros valores de cada tupla. Tenga en cuenta que este ejemplo compara el primer valor de cada tupla para ordenar. Para ordenar por el segundo valor, reemplace fst con snd.

Verá que la función sortBy es muy genérica, ya que le permite definir la función utilizada para comparar los valores. La función toma dos argumentos y debe devolver uno de LT, EQ o GT. Tenga en cuenta que la función compare requiere que ambos argumentos deriven de Ord. La función auxiliar on se puede encontrar en el módulo Data.Function. La función sortBy se encuentra en el módulo Data.List.

EDIT: Aquí hay un ejemplo de trabajo completo que ordena una lista de tuplas comparando sus primeros valores e imprime las 2 primeras tuplas de la lista resultante. Tenga en cuenta que reemplacé el on del ejemplo anterior con una función equivalente que muestra lo que hace on internamente.

import Data.Function 
import Data.List 

main = print $ mySort [("foo", 1), ("bar", 2), ("baz", 3), ("quux", 4)] 2 

mySort list x = take x $ sortBy (\ x y -> compare (fst x) (fst y)) list 

EDIT: Como Tom Lokhorst señaló en su comentario, la función del módulo de comparingData.Ord es un reemplazo más fácil de leer/acceso directo para on compare, por lo que el anterior también se podría escribir como sortBy (comparing fst).

+8

Tenga en cuenta que la función 'comparing' de' Data.Ord' es la misma que 'on compare'. Entonces también puedes escribir 'sortBy (comparando fst) list'. –

+0

Bien, no sabía eso. – jkramer

+0

¿No deberías 'tomar 'antes de' ordenarBy'? mySort puede tomar potencialmente una lista infinita. –