Menu Close

Agrupamiento según valores

Definir la función

   agrupa :: Ord c => (a -> c) -> [a] -> Map c [a]

tal que (agrupa f xs) es el diccionario obtenido agrupando los elementos de xs según sus valores mediante la función f. Por ejemplo,

   ghci> agrupa length ["hoy", "ayer", "ana", "cosa"]
   fromList [(3,["hoy","ana"]),(4,["ayer","cosa"])]
   ghci> agrupa head ["claro", "ayer", "ana", "cosa"]
   fromList [('a',["ayer","ana"]),('c',["claro","cosa"])]
   ghci> agrupa length (words "suerte en el examen")
   fromList [(2,["en","el"]),(6,["suerte","examen"])]

Soluciones

import qualified Data.List as L
import Data.Map
 
-- 1ª definición (por recursión)
agrupa1 :: Ord c => (a -> c) -> [a] -> Map c [a]
agrupa1 _ []     = empty
agrupa1 f (x:xs) = insertWith (++) (f x) [x] (agrupa1 f xs)
 
-- 2ª definición (por plegado)
agrupa2 :: Ord c => (a -> c) -> [a] -> Map c [a]
agrupa2 f = L.foldr (\x -> insertWith (++) (f x) [x]) empty

3 soluciones de “Agrupamiento según valores

  1. Jesús Navas Orozco
    agrupa :: Ord c => (a -> c) -> [a] -> M.Map c [a]
    agrupa f = foldr (x -> M.insertWith (++) (f x) [x]) M.empty
  2. Chema Cortés
    agrupa :: Ord c => (a -> c) -> [a] -> Map c [a]
    agrupa f xs = fromListWith (++) [(f x, [x]) | x <- xs]
    • Chema Cortés

      Es extraño, pero fromListWith me cambia el orden de los valores del mapa.

      ghci> agrupa length ["hoy", "ayer", "ana", "cosa"]
      fromList [(3,["ana","hoy"]),(4,["cosa","ayer"])]
      

      Para ajustarse a los ejemplos, es necesario invertir la lista:

      agrupa :: Ord c => (a -> c) -> [a] -> Map c [a]
      agrupa f xs = fromListWith (++) [(f x, [x]) | x <- reverse xs]

Leave a Reply to Jesús Navas Orozco Cancel reply

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.