#list #recursion #f#
#Список #рекурсия #f#
Вопрос:
Я пытаюсь удалить дубликаты в списке с помощью этой функции. Он удаляет дубликаты, но возвращает список в обратном порядке. Я немного не уверен, как это исправить без уродливого решения.
Комментарии:
1. Использовать
foldback
?2. Не знаю, что это такое.
3. внутренняя лямбда-строка в
removeDuplicates
должна иметь имяfunc
илиadd
, но оставаться неизменной в коде; тем не менее, вам просто нужно изменить результирующий список, либо используяList.rev
, либо написав свой собственный.4. @Sehnsucht Как будет выглядеть такая обратная функция?
5. Вы можете просто использовать do
[] -> List.rev nlist
Ответ №1:
Уже есть другие ответы, которые показывают различные практические решения для этого, но я полагаю, вы заинтересованы в минимальных изменениях, чтобы заставить ваш код работать. При использовании аккумулятора в функциональном программировании вы часто в конечном итоге переворачиваете список по пути — стандартное решение для этого — перевернуть список в конце, что вы можете сделать с помощью List.rev
:
let rd list=
let rec func list nlist=
match list with
| [] -> List.rev nlist // Reverse the list before returning it
| x::xs ->
if not (isMember x nlist) then
func xs (x::nlist)
else
func xs nlist
func list []
Помимо добавления List.rev
, я также изменил последнюю строку на func list []
(там был ваш код add
, но это, вероятно, была опечатка). Я также перешел isMember x nlist <> true
на более идиоматический not (isMember x nlist)
.
Комментарии:
1. может быть еще более идиоматичным просто инвертировать
if
,else
блокировать и удалятьnot
Ответ №2:
Вы можете сделать это, чтобы удалить дубликаты:
Seq.distinct [1;1;2;4;4;5;6]
Он возвращает [1;2;4;5;6]
Комментарии:
1. На самом деле это не та практика, к которой я стремлюсь>. <
Ответ №3:
Мне не совсем понятно, какую помощь (или ее отсутствие) вы хотите получить от стандартных библиотечных функций в вашем решении.
Самый простой подход — просто использовать List.distinct
List.distinct [1;1;2;4;4;5;6];;
val it : int list = [1; 2; 4; 5; 6]
Вы могли бы создать версию, используя foldBack
let distinct lst =
List.foldBack (fun v lst' ->
if List.contains v lst' then lst'
else v::lst') lst []
Это приводит к тому же результату:
distinct [1;1;2;4;4;5;6];;
val it : int list = [1; 2; 4; 5; 6]
Если вы тоже хотите создать свой собственный foldBack
…
let rec foldBack f lst z =
match lst with
|[] -> z
|x::xs -> f x (foldBack f xs z)
Обратите внимание, что я пытаюсь не писать одну большую функцию, которая делает все, а вместо этого пытаюсь создать решение из серии повторно используемых компонентов — это хорошая привычка при работе на функциональных языках.