【问题标题】:Adding no value to return list不向返回列表添加任何值
【发布时间】:2016-05-31 03:37:35
【问题描述】:

我无法理解 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],因为我不能在该声明中省略 else。 我也有针对性的签名 -> int list -> int -> int list 我得到了别的东西。

问题号也是如此。 2 我想提供一个整数并打印从 0 到这个整数的每个数字 n 次(其中 n 是迭代值): 例子: 乘数值 3;; 输出:[1;2;2;3;3;3]

我能做的最好的就是创建列表列表。

返回元素时我错过了什么? 如何在退货中添加任何内容
例如:如果 x=n 则 n 否则 AddNothingToTheReturn

【问题讨论】:

标签: list f#


【解决方案1】:

使用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)

这个遍历原始列表一次,并且(可能更短)新形成的列表一次。

【讨论】:

    【解决方案2】:

    前面的答案非常地道。这是一种避免使用 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]
    

    If 语句是 F# 中的表达式,它们返回一个值。在这种情况下,IF 和 ELSE 分支都必须返回相同类型的值。使用 Some/None(选项类型)可以解决这个问题。在某些情况下,您只需使用 If 就可以逃脱惩罚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2022-01-05
      相关资源
      最近更新 更多