[英]lists of lists haskell
我有一个简单的问题,我是Haskell的新手,正在尝试学习很多东西。 我如何连接例如
[( (0,1) , [1,2,3]) , ((1,2) , [7,8,9]) ,((0,1) , [4,5,6]) ] to [[1,2,3,4,5,6] , [7,8,9]]
我要串联具有成对的第一个元素的列表。 我试过了
map concat list
map (\t -> (filter (==).first) list ) list
但是第一个不起作用,第二个给出错误。 有任何想法吗?
使用Data.List
和Data.Function.on
的几个函数,它变成:
import Data.List (sortBy, groupBy)
import Data.Function (on)
sortByFirst :: Ord a => [(a, b)] -> [(a, b)]
sortByFirst = sortBy (compare `on` fst)
groupBy
函数期望对数据进行排序,因此我们必须首先按每个内部元组进行排序(即按((a, b), [x,y,z])
的(a, b)
进行排序)
groupByFirst :: Eq a => [(a, b)] -> [[(a, b)]]
groupByFirst = groupBy ((==) `on` fst)
然后我们使用groupBy
将结果的元组列表分组为元组列表列表,其中每个内部列表共享相同的第一个元素。
squishByFirst :: (Eq a, Ord a) => [(a, b)] -> [[b]]
squishByFirst = (map . concatMap) snd . groupByFirst . sortByFirst
然后我们在snd
上使用一些奇特的映射,将其滚动到每个内部列表中,拉出第二个元素(列表),将它们组合在一起,然后返回结果。 这等效于:
squishByFirst xs =
let grouped = groupByFirst . sortByFirst $ xs
in [concat [ys | (_, ys) <- g] | g <- grouped]
您也可以将其实现为Map.insertWith
的折叠
import Data.Map (elems, empty, insertWith)
squishByFirst :: Ord k => [(k, [v])] -> [[v]]
squishByFirst = elems . mkMap
where
mkMap = foldr (uncurry (insertWith (++))) empty
或任何Monoid:
squishByFirst :: (Ord k, Monoid vs) => [(k, vs)] -> [vs]
squishByFirst = elems . mkMap
where
mkMap = foldr (uncurry (insertWith mappend)) empty
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.