我在理解F#如何工作方面遇到了问题。我来自C#,我认为我正在努力使F#像C#一样工作。我最大的问题是以正确的格式返回值。
实施例: 假设我有一个带有整数列表和整数的函数。 函数应该打印一个索引列表,其中列表匹配的值传递整数。
我的代码:
let indeks myList n = myList |> List.mapi (fun i x -> if x=n then i else 0);;
indeks [0..4] 3;;
然而它返回:
val it : int list = [0; 0; 0; 3; 0]
而不仅仅是[3]因为我不能在该陈述中忽略其他。 我也有针对性的签名 - > int list - > int - > int list,我得到了别的东西。
同样的问题没有。 2我想提供一个整数并打印从0到这个整数n次的每个数字(其中n是迭代值): 例: MultiplyValues 3 ;; 输出:[1; 2; 2; 3; 3; 3]
我能做的最好的事情就是创建列表清单。
返回元素时我错过了什么?
如何在回程中添加任何内容
例如:如果x = n则n else AddNothingToTheReturn
答案 0 :(得分:5)
使用List.choose
:
let indeks lst n =
lst
|> List.mapi (fun i s -> if s = n then Some i else None)
|> List.choose id
抱歉,我没有注意到你有第二个问题。为此,您可以使用List.collect
:
let f (n : int) : list<int> =
[1 .. n]
|> List.collect (fun s -> List.init s (fun t -> s))
printfn "%A" (f 3) // [1; 2; 2; 3; 3; 3]
请阅读the documentation for List.collect了解详情。
修改强>
关注s952163
的主要内容,这是第一个没有Option
类型的解决方案的另一个版本:
let indeks (lst : list<int>) (n : int) : list<int> =
lst
|> List.fold (fun (s, t) u -> s + 1, (if u = n then (s :: t) else t)) (0, [])
|> (snd >> List.rev)
这一次遍历原始列表一次,并且(可能短得多)新形成的列表一次。
答案 1 :(得分:1)
之前的答案非常惯用。这是一个避免使用Option类型和id的解决方案:
let indeks2 lst n =
lst
|> List.mapi (fun i x -> (i,x))
|> List.filter (fun x -> (fst x) % n = 0 )
|> List.map snd
您可以修改过滤功能以满足您的需求。
如果您计划生成大量序列,那么探索序列(列表)理解可能是个好主意:
[for i in 1..10 do
yield! List.replicate i i]
如果语句是F#中的表达式,则它们返回一个值。在这种情况下,IF和ELSE分支都必须返回相同类型的值。使用Some / None(选项类型)可以解决这个问题。在某些情况下,您只需使用If就可以逃脱。