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"])]

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. eliguivil
    import qualified Data.Map as Map
     
    agrupa :: Ord c => (a -> c) -> [a] -> Map.Map c [a]
    agrupa f [] = Map.empty
    agrupa f xs = aux Map.empty f xs
      where
        aux m f [] = m
        aux m f (x:xs) = aux
                         (Map.insertWith (++) (f x) [x] m)
                         f
                         xs
  2. albcercid
     
    agrupa :: Ord c => (a -> c) -> [a] -> M.Map c [a]
    agrupa f xs = crL (M.fromList []) (map t (reverse xs))
        where t x = (f x,[x])
              crL d [] = d
              crL d ((a,b):ys) = crL (M.insertWith (++) a b d) ys
  3. enrnarbej
    import qualified Data.Map as M
    import Data.List
    import Data.Ord
     
    agrupa :: Ord c => (a -> c) -> [a] -> M.Map c [a]
    agrupa f = M.fromList
             . map (xs -> (f (head xs), xs))
             . groupBy (x y -> f x == f y)
             . sortBy (comparing f)

Leave a Reply to enrnarbej Cancel reply

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