简体   繁体   English

F#递归函数:使列表项唯一

[英]F# Recursive Functions: make list items unique

let rec isolate (l:'a list) = 
    match l with
    | [] -> []
    | x::xs ->
        if memberof(x,xs)
        then remove (x,l)
        else isolate xs

I've already created functions memberof and remove, the only problem is that when line 6 remove(x,l) executes it doesn't continue with isolate(xs) for continued search through the list. 我已经创建了函数memberof和remove,唯一的问题是当第6行remove(x,l)执行时,它不会继续使用isolate(xs)继续搜索列表。

Is there a way to say, 有没有办法说,

if x then f(x) and f(y)

?

As you are using F# immutable lists, the result of remove needs to be stored somewhere: 当您使用F#不可变列表时, remove的结果需要存储在某处:

let rec isolate (l:'a list) = 
    match l with
    | [] -> []
    | x::xs ->
        if memberof(x,xs)
        then
            let xs = remove (x,l)
            isolate xs
        else isolate xs

To answer your more general question: 要回答更一般的问题:

let f _ = ()
let f' z = z

let x = true
let y = 42
let z = 3.141

if x then
    f y
    f' z |> ignore

The ignore is needed here because in F# there are no statements, just expressions, so you can think of if x then f' z as 这里需要ignore因为在F#中没有语句,只有表达式,所以你可以想到if x then f' zif x then f' z as

if x then
    f' z
else
    ()

and thus the first branch needs to return () as well. 因此第一个分支也需要返回()

In addition to CaringDev's answer. 除了CaringDev的答案。
You may look at this simple solution. 你可以看看这个简单的解决方案。
It is worth note, that it's not a fastest way to do this. 值得注意的是,这不是最快的方法。

let rec isolate (acc : 'a list) (l : 'a list) = 
  match l with
  | [] -> acc
  | head :: tail -> 
    if memberof (head, tail)
    then remove (head, tail) |> isolate (acc @ [head])
    else isolate (acc @ [head]) tail

let recursiveDistinct = isolate []
let uniqValues = recursiveDistinct [ 1; 1; 2; 3] //returns [1;2;3]
let isolate list =
    let rec isolateInner searchList commonlist =
        match searchList with
        | x::xs ->
            if (memberof commonlist x) then
                isolateInner xs commonlist
            else
                let commonlist = (x :: commonlist)
                isolateInner xs commonlist
        | [] -> reverse commonlist
    isolateInner list []

This is part of an answer to your larger problem . 这是解决您的大问题的一部分

Notice that this does not use remove . 请注意,这不使用remove Since you have to pass over each item in the original list and list are immutable, it is better to create a new list and only add the unique items to the new list, then return the new list. 由于您必须传递原始列表中的每个项目并且列表是不可变的,因此最好创建新列表并仅将唯一项目添加到新列表,然后返回新列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM