在 F# 中是否有更通用的方法对集合进行迭代、过滤和应用操作?

发布于 2024-12-07 15:29:29 字数 511 浏览 1 评论 0原文

让我们看一下这段代码:

open System
open System.IO

let lines = seq {
  use sr = new StreamReader(@"d:\a.h")
  while not sr.EndOfStream do yield sr.ReadLine()
}

lines |> Seq.iter Console.WriteLine
Console.ReadLine()

在这里,我正在读取 seq 中的所有行,并使用 Seq.iter 来检查它。如果我有一个列表,我将使用 List.iter,如果我有一个数组,我将使用 Array.iter。是否有一个更通用的遍历函数我可以使用,而不必跟踪我拥有的集合类型?例如,在 Scala 中,我只需调用 foreach 并且无论我使用的是 List、Array 还是 Seq,它都会起作用。

我做错了吗?

Let's take this code:

open System
open System.IO

let lines = seq {
  use sr = new StreamReader(@"d:\a.h")
  while not sr.EndOfStream do yield sr.ReadLine()
}

lines |> Seq.iter Console.WriteLine
Console.ReadLine()

Here I am reading all the lines in a seq, and to go over it, I am using Seq.iter. If I have a list I would be using List.iter, and if I have an array I would be using Array.iter. Isn't there a more generic traversal function I could use, instead of having to keep track of what kind of collection I have? For example, in Scala, I would just call a foreach and it would work regardless of the fact that I am using a List, an Array, or a Seq.

Am I doing it wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不知所踪 2024-12-14 15:29:29

您可能需要也可能不需要跟踪您处理的集合类型,具体取决于您的情况。

在对项目进行简单迭代的情况下,没有什么可以阻止您在 F# 中的列表或数组上使用 Seq.iter:它将在数组和列表上工作,因为两者也是序列,或 从 .NET 的角度来看,IEnumerable。在数组上使用 Array.iter 或在列表上使用 List.iter 只会根据每种类型集合的特定属性提供更有效的遍历实现。作为Seq.iter的签名 Seq.iter : ('T -> unit) -> seq<'T> -> unit 表明您不关心遍历后的类型 'T

在其他情况下,如果您关心进一步的组合,您可能需要考虑输入和输出参数的类型并使用专门的函数。例如,如果您需要过滤列表并继续使用结果,则

List.filter : ('T -> bool) -> 'T 列表 -> 'T list 会完整保留底层集合的类型,但是 Seq.filter : ('T -> bool) -> seq<'T> -> seq<'T> 应用于列表将返回一个序列,而不是列表:

let alist = [1;2;3;4] |> List.filter (fun x -> x%2 = 0) // alist is still a list
let aseq = [1;2;3;4] |> Seq.filter (fun x -> x%2 = 0) // aseq is not a list anymore

You may or may not need to keep track of what type of collection you deal with, depending on your situation.

In case of simple iterating over items nothing may prevent you from using Seq.iter on lists or arrays in F#: it will work over arrays as well as over lists as both are also sequences, or IEnumerables from .NET standpoint. Using Array.iter over an array, or List.iter over a list would simply offer more effective implementations of traversal based on specific properties of each type of collection. As the signature of Seq.iter Seq.iter : ('T -> unit) -> seq<'T> -> unit shows you do not care about your type 'T after the traversal.

In other situations you may want to consider types of input and output arguments and use specialized functions, if you care about further composition. For example, if you need to filter a list and continue using result, then

List.filter : ('T -> bool) -> 'T list -> 'T list will preserve you the type of underlying collection intact, but Seq.filter : ('T -> bool) -> seq<'T> -> seq<'T> being applied to a list will return you a sequence, not a list anymore:

let alist = [1;2;3;4] |> List.filter (fun x -> x%2 = 0) // alist is still a list
let aseq = [1;2;3;4] |> Seq.filter (fun x -> x%2 = 0) // aseq is not a list anymore
游魂 2024-12-14 15:29:29

Seq.iter 也适用于列表和数组。

类型 seq 实际上是接口 IEnumerable<'T> 的别名,listarray 都实现了该接口。因此,正如 BLUEPIXY 所指出的,您可以在数组或列表上使用 Seq.* 函数。

一种看起来不太实用的方法如下:

for x in [1..10] do
    printfn "%A" x

Seq.iter works on lists and arrays just as well.

The type seq is actually an alias for the interface IEnumerable<'T>, which list and array both implement. So, as BLUEPIXY indicated, you can use Seq.* functions on arrays or lists.

A less functional-looking way would be the following:

for x in [1..10] do
    printfn "%A" x
丑丑阿 2024-12-14 15:29:29

List 和 Array 被视为 Seq。

let printAll seqData =
  seqData |> Seq.iter (printfn "%A")
  Console.ReadLine() |> ignore

printAll lines
printAll [1..10]
printAll [|1..10|]

List and Array is treated as Seq.

let printAll seqData =
  seqData |> Seq.iter (printfn "%A")
  Console.ReadLine() |> ignore

printAll lines
printAll [1..10]
printAll [|1..10|]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文