F#:将旧的IEnumerable.GetEnumerator()样式的迭代器转换为seq
在.NET标准库中仍然有一些东西只向外界公开老式的F#:将旧的IEnumerable.GetEnumerator()样式的迭代器转换为seq,f#,F#,在.NET标准库中仍然有一些东西只向外界公开老式的IEnumerable.GetEnumerator()iterator,这对F#seq处理风格不是很友好。我在谷歌上快速搜索如何将Regex.Match(…)的结果组放入一个我可以处理的列表,但没有找到任何东西 我有这个: open System.Text.RegularExpressions let input = "args=(hello, world, foo, bar)" let mtc = Regex.Match( input, "ar
IEnumerable.GetEnumerator()
iterator,这对F#seq处理风格不是很友好。我在谷歌上快速搜索如何将Regex.Match(…)
的结果组放入一个我可以处理的列表,但没有找到任何东西
我有这个:
open System.Text.RegularExpressions
let input = "args=(hello, world, foo, bar)"
let mtc = Regex.Match( input, "args=\(([\w\s,]+)\)" )
我希望以seq或列表的形式访问mtc.Groups
,但它不允许这样做,因为它是一个古老的ICollection
,它只公开一个GetEnumerator()
方法。所以当你能做的时候
mtc.Groups.[1].Value
你不能这样做
mtc.Groups |> Seq.skip 1 // <=== THIS QUESTION IS ABOUT HOW TO ACHIEVE THIS
mtc.Groups |>Seq.skip 1//
(为清晰起见,GroupCollection
实现了ICollection
,它是IEnumerable
的子接口)
因此,问题是:如何将
GetEnumerator()
巧妙地转换为seq?答案其实并不复杂,只是为下一个在谷歌上搜索快速答案的人准备的。其思想是将可怕的命令性封装在seq{…}
表达式中,然后将结果seq
转换为您碰巧知道结果的任何内容
seq { let i = mtc.Groups.GetEnumerator() in while i.MoveNext() do yield i.Current }
|> Seq.cast<Text.RegularExpressions.Group>
|> Seq.map (fun m -> m.Value)
|> List.ofSeq
正如我所说,我把它放在这里是为了下一个谷歌的答案,所以改进、建议、否决票、欺骗标志都是受欢迎的
编辑:根据第一条评论中的建议,
Seq.cast
足够聪明,可以直接吃IEnumerable
s。因此,seq表达式是完全不必要的,答案就是seq.cast
!让我知道我是否应该删除这个问题。你不应该需要seq
表达式-mtc.Groups |>seq.cast
也应该有效。哦,是的,确实如此。我没有注意类型Seq.cast
takes。非常感谢。不出所料,这确实是个骗局。我猜我没有找到原件,因为它没有提到GetEnumerator()
一次。除此之外,完全一样,同意。
seq { let i = mtc.Groups.GetEnumerator() in while i.MoveNext() do yield i.Current }
|> Seq.cast<Text.RegularExpressions.Group>
|> Seq.map (fun m -> m.Value)
|> List.ofSeq
val input : string = "args=(hello, world, foo, bar)"
val mtc : Match = args=(hello, world, foo, bar)
val it : string list = ["args=(hello, world, foo, bar)"; "hello, world, foo, bar"]