如何从Map构建键列表?

时间:2013-10-08 15:29:15

标签: f#

我正在尝试从Map构建一个键列表。这就是我的工作:

Map.fold (fun state key value -> state::value) [] [("one", 1); ("two", 2)]

但是,位state::value会产生此错误:

tryout.fs(146,48): error FS0001: Type mismatch. Expecting a
    'a    
but given a
    'a list

我的代码出了什么问题?

2 个答案:

答案 0 :(得分:4)

其他人已经发布了很好的解决方案,所以只是回答你的问题并解释你的代码有什么问题 - 因为你正在使用Map.fold我假设你的数据源实际上是一个地图而不是一个列表: / p>

let sample = Map.ofSeq [("one", 1); ("two", 2)]

这是您的原始解决方案,并且可以并排运行:

// Original version - attempts to add 'state' as the new head of a list 'value'
Map.fold (fun state key value -> state::value) [] sample
// Corrected version - adds 'key' as the new head of a list 'state'
Map.fold (fun state key value -> key::state) [] sample

关键是::运算符需要左侧有一个值(此处为string),右侧需要另一个列表(此处为string list)。您正确创建了一个空列表[]作为初始状态。

如果要在折叠期间添加新密钥,则需要将现有列表(state)作为::的正确参数和新密钥(key)传递为左参数 - 创建一个新列表,其中包含键作为第一个元素,所有剩余元素作为列表的其余元素( tail )。

所以1)::的参数顺序很重要,2)你想要收集键而不是值,但如果你正在收集值,它将以相同的方式工作。

答案 1 :(得分:1)

两个问题:

- 您不会传递地图而是传递列表。

- 状态(折叠键的结果)和值(int)相反。

您可以将列表转换为地图(请参阅Daniel的评论):

["one", 1; "two", 2]
|> Map.ofList
|> Map.fold (fun state key value -> value :: state) [];;
// val it : int list = [2; 1]

或者,您可以折叠元组列表:

["one", 1; "two", 2]
|> List.fold (fun state (key, value) -> value :: state) [];;
// val it : int list = [2; 1]