不为返回列表

时间:2016-05-30 06:55:16

标签: list f#

我在理解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

2 个答案:

答案 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就可以逃脱。