从列表中删除f#

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从列表中删除f#相关的知识,希望对你有一定的参考价值。

我今天晚上一直在使用f#中的列表(创建,添加,搜索等),并且最近卡在列表项删除上。代码很简单。

let menu = [("pizza",17);("hotdog",5);("burger", 12);("drink",3);
("milkshake",4)]

//If key is in dictionary , return new dictionary with value removed
//otherwise return dictionary unchanged
let rec remove dict key =
    match dict with
    //if the list is empty, return an empty list
    | [] -> []
    //if the list is not empty and the head meets the removing criteria
    //return a list obtained by reiterating the algorithm on the tail
    //of the list
    | (k,v) :: tl when k = key -> tl :: remove tl key
    //if the list is not empty and the head does not meet the removing criteria
    //return a list obtained by appending the head to a list obtained by
    //reiterating algorithm on tail of the list 
    | (k,v) :: tl -> (k,v) :: remove tl key

错误来自函数的最后一行| (k,v) :: tl -> (k,v) :: remove tl key。显然,它不会将(k,v)识别为列表的头部,而只会看到带有值的元组。这是有道理的,我不知道我还能期待什么,但问题是我不知道如何解决它。我尝试将元组放在列表中,比如[(k,v)],但这让事情变得更糟。我甚至尝试过| hd :: tl -> hd :: remove tl key,但我有完全相同的问题。我写的每个其他函数都接受了hd和tl作为模式匹配中的列表。

我该如何解决这个问题?

答案

第二名后卫是错的。您正在使用尾部两次,并且因为您在cons操作中将它用作第一个参数,所以它不会键入check(它需要单个元素,而不是列表)。

将其更改为:

| (k,v) :: tl when k = key -> remove tl key
另一答案

我看到你正在犯的另一个错误。这是一个概念上的错误,而不是代码中的错误,但除非您了解错误,否则会导致更多错误。你写了:

我写的每个其他函数都接受了hd和tl作为模式匹配中的列表。

(强调我的)。你的错误是认为当你写hd :: tl时,hdtl都是列表。你是对的一半:tl确实是该语法中的列表,但hd是一个单项。证明:

let theList = [1; 2; 3; 4; 5]
printfn "The list: %A" theList
// Prints "The list: [1; 2; 3; 4; 5]"
match theList with
| [] -> printfn "The list was empty"
| hd :: tl -> printfn "Head was %A and tail was %A" hd tl
// Prints "Head was 1 and tail was [2; 3; 4; 5]"

当您在模式匹配中使用语法hd :: tl时,它会将列表拆分为第一个项目(头部)和列表的其余部分(尾部)。当你在正常表达式中使用语法hd :: tl时(例如,在不是模式匹配的任何地方),你将获得一个名为tl的列表和一个名为hd的项目,并将该项目添加到列表中,从而产生一个品牌 - 新列表在前面有一个项目比前一个列表更多。

如果你写的话我引用的句子是正确的:

我编写的每个其他函数都接受tl作为列表,并将hd作为模式匹配中的列表项。

我希望这可以帮助您更好地理解F#列表!

以上是关于从列表中删除f#的主要内容,如果未能解决你的问题,请参考以下文章

用另一个列表替换主活动中的列表并从视图中删除旧列表

从 F# 中的列表中删除 nans

在android中显示隐藏片段

如何通过单击适配器类中代码的项目中的删除按钮来删除列表视图中的项目后重新加载片段?

如何从片段内的列表视图打开链接网址?

如何将列表视图中的数据从一个片段发送到另一个片段