Не уверен, что понимаю, в чем проблема. Как по мне, решение может быть выражено довольно четко:
- Возьмите элемент заголовка списка для дедупликации.
- Если он не является членом списка результатов, добавьте элемент head к списку результатов
- Если он уже является членом - пропустите его
- Дублируйте (повторите 1-3) хвост
Реализация просто следует description:
let rec is_member key = function
| [] -> false
| (k, _)::tail ->
if k = key then true
else is_member key tail
;;
let dedup list =
let rec aux acc = function
| [] -> List.rev acc
| ((k, v) as hd)::tl ->
if is_member k acc then aux acc tl
else aux (hd::acc) tl
in aux [] list
;;
utop # dedup [("key",32);("key",78);("anotherKey",12)];;
- : (string * int) list = [("key", 32); ("anotherKey", 12)]
Что касается стандартной библиотеки (и List в частности), вы не можете достичь своей цели, используя List.filter
- потому что эта функция не накапливает результат, а просто перебирает элементы списка один за другим. Если вам нужен накопленный результат, вы должны использовать что-то. например, вместо fold_left
, например:
let dedup_list list =
List.fold_left (fun acc ((k, v) as el) -> if is_member k acc then acc else el::acc) [] list
|> List.rev
;;
utop # dedup_list [("key",32);("key",78);("anotherKey",12)];;
- : (string * int) list = [("key", 32); ("anotherKey", 12)]