4
\$\begingroup\$

Considering the problem:

Make a function to find the common elements of the lists in a list of lists.

Example:

common ( [ [1,2,3,3,5,11], [2,2,2,3,3,5], [2,2,3,3,4,5,6,7,18,19], [3,5,10,15] ] ) = [3, 5].

I came up with this solution:

import Data.List(group, nub, sort)

-- |
-- This function returns the elements common to all lists in a list of lists.
--
commonXss :: Ord a => [[a]] -> [a]
commonXss xss = concat [x | (x, y) <- countElemAppearsXss xss, y == length xss]

-- |
-- This function takes a list of lists and returns a list of tuples. Each tuple
-- (x, y) is made of x == [element] and y == number of lists in which that
-- element appeared.
-- 
countElemAppearsXss :: Ord a => [[a]] -> [([a], Int)]
countElemAppearsXss xss = freq $ sort $ concat $ map nub xss

-- |
-- This function returns a list of tuples. Each tuple (x, y) is made of
-- x == [element] and y == it's frequency.
-- 
freq :: Ord a => [a] -> [([a], Int)]
freq xs = map (\x -> ([head x], length x)) . group . sort $ xs

Is there a simpler way, more straightforward way that I'm missing? Perhaps in a library? How about the style?

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

This problem is just a matter of folding using the intersect function of Data.List, then deduplicating the result using nub.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.