Предполагая, что ваши списки все обмундирование, в том, что ни один список не содержит два различных элемента (т.е. [2, 3]
), вы могли бы вместо того, чтобы поставить этот вопрос с точки зрения длины:
> import Control.Arrow
> -- Equivalent to `\x -> (head x, length x)`
> :t head &&& length
head &&& length :: [a] -> (a, Int)
> (head &&& length) [2, 2, 2]
(2, 3)
>
> let myData = <what you have above>
> map (head &&& length) myData
[(2, 1), (2, 2), (3, 1), (3, 3), (5, 1)]
Теперь вы можете сгруппировать их по первому элемент
> import Data.List
> :t groupBy
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
> import Data.Function
> :t on
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
> :t on (==) fst
on (==) fst :: Eq b => (b, b1) -> (b, b1) -> Bool
> :t groupBy (on (==) fst)
groupBy (on (==) fst) :: Eq b -> [(b, b1)] -> [[(b, b1)]]
> groupBy (on (==) fst) $ map (head &&& length) myData
[[(2,1),(2,2)],[(3,1),(3,2),(3,3)],[(5,1)]]
Затем вы можете выбрать срок с крупнейшим snd
:
> :t maximumBy
maximumBy :: (a -> a -> Ordering) -> [a] -> a
> import Data.Ord
> :t comparing
comparing :: Ord a => (b -> a) -> b -> b -> Ordering
> :t comparing snd
comparing snd :: Ord a => (a1, a) -> (a1, a) -> Ordering
> :t maximumBy (comparing snd)
maximumBy (comparing snd) :: Ord a -> [(a1, a)] -> (a1, a)
> :t map (maximumBy (comparing snd))
map (maximumBy (comparing snd)) :: Ord a => [[(a1, a)]] -> [(a1, a)]
> map (maximumBy (comparing snd)) $ groupBy (on (==) fst) $ map (head &&& length) myData
[(2, 2), (3, 3), (5, 1)]
А теперь, если вы хотите, вы можете преобразовать его обратно в списки с помощью replicate
:
> map (uncurry (flip replicate)) $ map (maximumBy (comparing snd)) $ groupBy (on (==) fst) $ map (head &&& length) myData
[[2, 2], [3, 3, 3], [5]]
Последняя функция будет выглядеть
import Data.List (groupBy, maximumBy)
import Data.Ord (comparing)
import Data.Function (on)
import Control.Arrow ((&&&))
biggestUnique :: [[Int]] -> [[Int]]
biggestUnique
= map (uncurry (flip replicate)) -- Convert back to lists
. map (maximumBy (comparing snd)) -- Select by the maximum length
. groupBy ((==) `on` fst) -- Group by the element value
. map (head &&& length) -- Reformulate in terms of length
И вы можете сжать map
сек в один, но я думаю, что он делает его менее читаемым.
ВНИМАНИЕ: Это не будет работать должным образом, если ваши элементы не уникальны в каждом подсписке.
имеет префикс или подмножество? (так что '[2,3]' подмножество '[3,3,2]' в вашем смысле или нет?) – Carsten
также: ваши образцы все mutliple экземпляры одного и того же значения - можем ли мы использовать это свойство или это случайность? – Carsten
Если я правильно понимаю, это не самый эффективный способ хранения этих данных. Каков контекст? –