C# 在F中访问IEnumerable中的项#
我试图在F#中使用Youtube.Net API,但在访问返回到userPlaylists.Entries属性的IEnumerable时遇到了一个问题。下面是我测试过的c代码,但是我似乎无法返回f中IEnumerable集合中的单个项C# 在F中访问IEnumerable中的项#,c#,f#,youtube,C#,F#,Youtube,我试图在F#中使用Youtube.Net API,但在访问返回到userPlaylists.Entries属性的IEnumerable时遇到了一个问题。下面是我测试过的c代码,但是我似乎无法返回f中IEnumerable集合中的单个项 但是,这似乎返回了一种“播放列表选项”,而不是“播放列表”。有人能建议从IEnumerable中检索单个项的正确方法吗?Seq.tryPick类似于IEnumerable.FirstOrDefault,后面是一个类型转换,它没有您想要的语义。与IEnumerabl
但是,这似乎返回了一种“播放列表选项”,而不是“播放列表”。有人能建议从IEnumerable中检索单个项的正确方法吗?
Seq.tryPick
类似于IEnumerable.FirstOrDefault
,后面是一个类型转换,它没有您想要的语义。与IEnumerable.Single
类似。首先是类型转换,这是朝着正确方向迈出的一步(假设您希望在找不到任何匹配项时抛出异常,如IEnumerable.Single
),但由于您实际上不需要类型转换,我认为您真正想要的是,语义上与IEnumerable相同。首先:
let UserPlaylists = Request.GetPlaylistsFeed "username"
let pl = UserPlaylists.Entries |> Seq.find (fun x -> x.Title = "playlistname")
也就是说,如果您确实需要
IEnumerable.Single
的语义,而不是IEnumerable.First
,请忽略此项并查看@JoelMueller的答案。使用选项。get
方法从选项中获取值
Seq.tryPick(fun x -> if x.Title="playlistname" then Some(x) else None)
|> Option.get
虽然在F#中,我认为显式处理空案例比使用异常传播更为惯用
let value = Seq.tryPick(fun x -> if x.Title="playlistname" then Some(x) else None)
match value with
| None ->
// No matching elements. Take corrective action
| Some value ->
// The value i'm looking for
如果扩展方法未找到匹配项,则会引发异常;如果找到多个匹配项,则也会引发异常。F#Seq
模块中没有直接等效项。最接近的是Seq.find
,类似于。如果没有找到匹配项,Single()
将抛出异常,但与不同。Single()
在找到匹配项后将立即停止查找,如果存在多个匹配项,则不会抛出错误
如果您确实需要“在多个匹配时抛出错误”行为,那么最简单的方法就是使用F#中的确切方法:
如果您不需要“如果有多个匹配项,则抛出”行为,那么您也不应该在C代码中使用.Single()
,.First()
会执行得更好,因为它一找到匹配项就停止查找
如果是我,为了简洁起见,我会使用Seq.tryFind
overSeq.tryPick
,并处理“未找到”的情况,而不是抛出错误
let userPlaylists = request.GetPlaylistsFeed("username")
let p = userPlaylists.Entries |> Seq.tryFind (fun x -> x.Title = "playlistname")
match p with
| Some pl ->
// do something with the list
| None ->
// do something else because we didn't find the list
或者,我也可以在不创建只引用一次的中间值的情况下执行此操作
request.GetPlaylistsFeed("username").Entries
|> Seq.tryFind (fun x -> x.Title = "playlistname")
|> function
| Some pl ->
// do something with the list
| None ->
// do something else because we didn't find the list
我非常喜欢管道操作员…如果在序列中找不到所需项目,您想怎么做?
open System.Linq
let p = userPlaylists.Entries.Single(fun x -> x.Title = "playlistname")
let userPlaylists = request.GetPlaylistsFeed("username")
let p = userPlaylists.Entries |> Seq.tryFind (fun x -> x.Title = "playlistname")
match p with
| Some pl ->
// do something with the list
| None ->
// do something else because we didn't find the list
request.GetPlaylistsFeed("username").Entries
|> Seq.tryFind (fun x -> x.Title = "playlistname")
|> function
| Some pl ->
// do something with the list
| None ->
// do something else because we didn't find the list