数组值的Seq和Array之间的差异

时间:2010-09-24 15:43:17

标签: .net f#

我在F#中很新。

我猜数组仍然是集合,所以我可以使用Seq来迭代这个数组:

[|"a"; "b"|] |> Seq.map (fun f -> printfn "a") |> ignore;;

但这不起作用 - 它什么都不打印。 另一方面,如果我使用Array,它会打印字符串:

[|"a"; "b"|] |> Array.map (fun f -> printfn "a") |> ignore;;

为什么?

2 个答案:

答案 0 :(得分:7)

Array.map构建另一个数组 - 这意味着它必须急切地这样做。您无法构建数组并说“我会在您需要时填写值。”

序列,另一方面, 懒惰地评估......只有当您要求结果序列中的值时才会评估映射。正如Seq.map的文档中所述:

  

将使用MoveNext在要求元素时应用给定的函数   从对象中检索的枚举数的方法。

如果你熟悉LINQ,它基本上是Enumerable.Select(懒洋洋地产生一个序列)和Array.ConvertAll(急切地投射一个数组)之间的区别。

这些都不是迭代在数组或序列上的方式 - 它们是投影。正如Stringer Bell所说,Array.iterSeq.iter是迭代的合适函数。

答案 1 :(得分:5)

如果你想迭代你的收藏,你必须使用Seq.iter,就像那样:

[|"a"; "b"|] |> Seq.iter (fun f -> printfn "%A" f);;

如果只是在数组上进行迭代,你也可以使用Array.iter

[|"a"; "b"|] |> Array.iter (fun f -> printfn "%A" f);;

另一个(也就是更短的)替代方案是直接将您的值汇总到printfn "%A"函数:

[|"a"; "b"|] |> printfn "%A";;

将打印[|"a"; "b"|]。请注意,在这种情况下,F#的打印方式与编码时完全相同。