List 如何在递归F#函数中创建新列表?

List 如何在递归F#函数中创建新列表?,list,recursion,functional-programming,f#,List,Recursion,Functional Programming,F#,我正在创建一个递归函数,该函数将查看现有列表,并创建一个新列表,但没有重复项。我正在删除现有列表的标题,并检查新列表以查看它是否包含该元素。如果没有,那么我添加它,因为我知道它不是重复的 到目前为止,我有这个代码 let newList = [] let rec filtered inputList = match inputList with | [] -> [] | h::t -> if List.contains h newList then filter

我正在创建一个递归函数,该函数将查看现有列表,并创建一个新列表,但没有重复项。我正在删除现有列表的标题,并检查新列表以查看它是否包含该元素。如果没有,那么我添加它,因为我知道它不是重复的

到目前为止,我有这个代码

let newList = []
let rec filtered inputList = 
  match inputList with
    | [] -> []
    | h::t -> if List.contains h newList then filtered t else h::(filtered t)

我知道在else语句中,我并没有将该元素预先添加到newList。在使用match语句时,是否有一种方法可以在if语句中执行多行代码?如何解决这个问题?

在函数式编程中,通常情况下,您不会附加到列表中,而是在递归函数中传递它,并在末尾像这样返回它

let distinct list =
    let rec filtered inputList outputList = 
      match inputList with
        | [] -> outputList
        | h::t -> if List.contains h outputList then (filtered t outputList) else (filtered t (h::outputList))

    filtered list []

printf "%A" (distinct [1; 2; 2; 3]) // [3; 2; 1]
我试图尽可能多地保留您的原始代码,以使差异更加明显。基本上,递归函数以空列表开始,最后返回包含唯一元素的列表

这更像是一个风格的问题,但我也会像这样把if分开

let distinct list =
    let rec filtered inputList outputList = 
      match inputList with
        | [] -> outputList
        | h::t when List.contains h outputList -> filtered t outputList
        | h::t -> filtered t (h::outputList)

    filtered list []

printf "%A" (distinct [1; 2; 2; 3]) // [3; 2; 1]

在函数式编程中,通常不会附加到列表,而是在递归函数中传递它,并在末尾像这样返回它

let distinct list =
    let rec filtered inputList outputList = 
      match inputList with
        | [] -> outputList
        | h::t -> if List.contains h outputList then (filtered t outputList) else (filtered t (h::outputList))

    filtered list []

printf "%A" (distinct [1; 2; 2; 3]) // [3; 2; 1]
我试图尽可能多地保留您的原始代码,以使差异更加明显。基本上,递归函数以空列表开始,最后返回包含唯一元素的列表

这更像是一个风格的问题,但我也会像这样把if分开

let distinct list =
    let rec filtered inputList outputList = 
      match inputList with
        | [] -> outputList
        | h::t when List.contains h outputList -> filtered t outputList
        | h::t -> filtered t (h::outputList)

    filtered list []

printf "%A" (distinct [1; 2; 2; 3]) // [3; 2; 1]

dee-see的解决方案有一个很好的特性,那就是它是尾部递归的。这意味着它可以轻松处理非常大的列表

但是,如果您不熟悉函数式编程,那么从一个更简单的版本开始可能会更容易,它接受一个输入列表并直接返回输出列表作为结果

这实际上非常接近你所拥有的。您需要实现的逻辑是:

  • 如果列表的其余部分中有一个元素,那么我们将跳过它
  • 如果该元素不在列表的其余部分,我们将附加它
为此,您不需要
newList
。只需检查
List.contains h t
,即可确保只返回每个重复元素的最后一次出现:

let rec filtered inputList = 
  match inputList with
  | [] -> []
  | h::t -> if List.contains h t then filtered t else h::(filtered t)

filtered [1;2;3;2;3;4;5;4;1]
与函数的唯一区别在于条件。dee-see的解决方案更为复杂,但它实现了相同的结果。与另一个答案一样,您可以在以下情况下使用

let rec filtered inputList = 
  match inputList with
  | [] -> []
  | h::t when List.contains h t -> filtered t 
  | h::t -> h::(filtered t)

dee-see的解决方案有一个很好的特性,那就是它是尾部递归的。这意味着它可以轻松处理非常大的列表

但是,如果您不熟悉函数式编程,那么从一个更简单的版本开始可能会更容易,它接受一个输入列表并直接返回输出列表作为结果

这实际上非常接近你所拥有的。您需要实现的逻辑是:

  • 如果列表的其余部分中有一个元素,那么我们将跳过它
  • 如果该元素不在列表的其余部分,我们将附加它
为此,您不需要
newList
。只需检查
List.contains h t
,即可确保只返回每个重复元素的最后一次出现:

let rec filtered inputList = 
  match inputList with
  | [] -> []
  | h::t -> if List.contains h t then filtered t else h::(filtered t)

filtered [1;2;3;2;3;4;5;4;1]
与函数的唯一区别在于条件。dee-see的解决方案更为复杂,但它实现了相同的结果。与另一个答案一样,您可以在以下情况下使用

let rec filtered inputList = 
  match inputList with
  | [] -> []
  | h::t when List.contains h t -> filtered t 
  | h::t -> h::(filtered t)
另一种方式:

let rec distinct = function
    | []   -> []
    | h::t -> h :: distinct (List.filter ((<>) h) t)
让rec distinct=函数
| []   -> []
|h::t->h::distinct(List.filter(()h)t)
另一种方式:

let rec distinct = function
    | []   -> []
    | h::t -> h :: distinct (List.filter ((<>) h) t)
让rec distinct=函数
| []   -> []
|h::t->h::distinct(List.filter(()h)t)

如果您是为了教育目的而这样做,请继续,但要意识到它的存在。如果您是为了教育目的而这样做,请继续,但要意识到它的存在。