Подтвердить что ты не робот

Подсчет уникальных элементов в списке

Есть ли прямая комбинация стандартных функций более высокого порядка для подсчета уникальных элементов в списке?

Например, результат для

[1, 1, 4, 0, 4, 4]

будет что-то вроде

[(1,2), (4,3), (0,1)]
4b9b3361

Ответ 1

Если порядок не важен, это работает:

map (\[email protected](x:_) -> (x, length xs)) . group . sort

group . sort предоставит вам список списков, в которых все элементы, равные друг другу, сгруппированы в один и тот же подсписк (без сортировки, только последовательные равные элементы будут сгруппированы вместе). Затем map превращает каждый подвыбор в (element, lengthOfSublist) -tuple.

Если вы хотите заказать результат по первому вхождению, вы можете использовать zip перед сортировкой, чтобы добавить индекс к каждому элементу, а затем после группировки снова сортировать по этому индексу, а затем удалить индекс.

Ответ 2

Использование разделов Data.Map и tuple:

 count = Map.fromListWith (+) . map (, 1)

(Добавить Map.toList, если вам нужен список.)

Ответ 3

Простейшей задачей было бы отсортировать элементы в порядке, использовать "группу", чтобы поместить их в под-списки равных элементов, а затем подсчитать элементы в каждом под-списке.

map (\xs -> (head xs, length xs)) . group . sort

Ответ 4

Если список содержит только целые числа, вы также можете использовать

 import qualified Data.IntMap as I

 countElems1 :: [Int] -> [(Int, Int)]
 countElems1 = I.toList . foldr (\k -> I.insertWith (+) k 1) I.empty 

(Не забывайте компилировать с оптимизацией, хотя в противном случае это будет в 2 раза медленнее, чем метод group . sort. С -O2 он немного быстрее на 14%.)

Вы также можете использовать один из multiset packages, что делает эту функцию такой же простой, как

 import qualified Math.Combinatorics.Multiset as S
 countElems4 = S.toCounts . S.fromList

но менее эффективен.

Все приведенные выше решения игнорируют исходный порядок.

Ответ 5

Как вы говорите, просто кодировать длину пробега по отсортированным данным: бесплатная онлайн-книга Real World Haskell имеет отличный пример. Вам нужно отсортировать список, прежде чем вы поместите его через runLengthEncoder.