基于一系列集合构建一个IEnumerable(Constructing an IEnumerable based on a collection of collections)

编程入门 行业动态 更新时间:2024-10-27 18:26:31
基于一系列集合构建一个IEnumerable(Constructing an IEnumerable based on a collection of collections)

下午好,

我有一个非常有趣的时间试图说服'收益'关键字以我能理解的方式运作,但不幸的是我没有太多的运气。 以下是该场景:

基于用户的属性,我想查找一组RSS源地址,并显示来自所有这些源的最近七篇文章,而不是每个这些源。 为此,我试图从每个Feed中构建最近五篇文章的集合,然后从这些文章中选取最近的七篇文章。 (非常枯燥的)伪代码类型过程如下所示:

查找该成员 获取成员的相关属性(组名) 查找该组的RSS源的地址 对于集合中的每个地址,获取最近的五篇文章并将它们放在另一个集合中 从后续收藏中挑选最新的七篇文章并展示它们。

我已经做了一些研究,并能够产生以下内容:

public static class RSSHelper { public static IEnumerable<SyndicationItem> GetLatestArticlesFromFeeds(List<string> feedList, short articlesToTake) { foreach (string Feed in feedList) { yield return GetLatestArticlesFromFeed(Feed).OrderByDescending(o => o.PublishDate).Take(articlesToTake).First(); } yield return null; } private static IEnumerable<SyndicationItem> GetLatestArticlesFromFeed(string feedURL) { // We're only accepting XML based feeds, so create an XML reader: SyndicationItem Result = new SyndicationItem(); int SkipCount = 0; for (int Curr = 1; Curr <= 5; Curr++) { try { XmlReader Reader = XmlReader.Create(feedURL); SyndicationFeed Feed = SyndicationFeed.Load(Reader); Reader.Close(); Result = Feed.Items.OrderByDescending(o => o.PublishDate).Skip(SkipCount).Take(1).Single(); SkipCount++; } catch (Exception ex) { // Do nothing, else the Yield will fail. } yield return Result; } } }

看起来发生的是我得到5个结果(articlesToTake是7,而不是5),偶尔整个SyndicationItem为空,或者它的属性为空。 我也确信这是一个解决这个问题的非常非常不好的方法,但是在这种情况下我找不到使用yield关键字的很多方向。

我确实发现了这个问题,但这并不能帮助我理解任何事情。

我正在尝试以这种方式实现,还是我只需要咬紧牙关并使用几个foreach循环?

Good afternoon,

I'm having a highly entertaining time trying to convince the 'yield' keyword to function in a way that I can understand, but unfortunately I'm not having much luck. Here's the scenario:

Based on the property of a user, I want to look up a set of RSS feed addresses and display the seven most recent articles from all of those feeds, not each of those feeds. To do so, I'm trying to build a collection of the five most recent articles from each feed, then take the 7 most recent from those. The (very dull) pseudo-code-type-process goes something like:

Look up the the member Get the relevant property ( a group name) for the member Look up the addresses of the RSS feeds for that group For each address in the collection, get the five most recent articles and place them in another collection Take the seven most recent articles from that subsequent collection and display them.

I've done some research and been able to produce the following:

public static class RSSHelper { public static IEnumerable<SyndicationItem> GetLatestArticlesFromFeeds(List<string> feedList, short articlesToTake) { foreach (string Feed in feedList) { yield return GetLatestArticlesFromFeed(Feed).OrderByDescending(o => o.PublishDate).Take(articlesToTake).First(); } yield return null; } private static IEnumerable<SyndicationItem> GetLatestArticlesFromFeed(string feedURL) { // We're only accepting XML based feeds, so create an XML reader: SyndicationItem Result = new SyndicationItem(); int SkipCount = 0; for (int Curr = 1; Curr <= 5; Curr++) { try { XmlReader Reader = XmlReader.Create(feedURL); SyndicationFeed Feed = SyndicationFeed.Load(Reader); Reader.Close(); Result = Feed.Items.OrderByDescending(o => o.PublishDate).Skip(SkipCount).Take(1).Single(); SkipCount++; } catch (Exception ex) { // Do nothing, else the Yield will fail. } yield return Result; } } }

What seems to be happening is that I get five results (articlesToTake is 7, not 5), and occasionally either the whole SyndicationItem is null, or properties of it are null. I'm also convinced that this is a really, really poorly performing approach to tackling this problem, but I can't find much direction on using the yield keyword in this context.

I did find this question but it's not quite helping me understand anything.

Is what I'm trying to do achievable in this way, or do I just need to bite the bullet and use a couple of foreach loops?

最满意答案

使用async将您的RSS源加载到内存中并await ,然后按日期对它们进行排序,并且只取第一个7

Morning,

Now that I don't feel like death warmed up, I've got it working! Thanks to @Rodrigo and @McKabue for their help in finding the eventual answer, and @NPSF3000 for pointing out my original stupidity!

I've settled on this as a result:

public static class RSSHelper { public static IEnumerable<SyndicationItem> GetLatestArticlesFromFeeds(List<string> feedList, short articlesToTake) { return GetLatestArticlesFromFeedsAsync(feedList, articlesToTake).Result; } private async static Task<IEnumerable<SyndicationItem>> GetLatestArticlesFromFeedsAsync(List<string> feedList, short articlesToTake) { List<Task<IEnumerable<SyndicationItem>>> TaskList = new List<Task<IEnumerable<SyndicationItem>>>(); foreach (string Feed in feedList) { // Call and start a task to evaluate the RSS feeds Task<IEnumerable<SyndicationItem>> T = Task.FromResult(GetLatestArticlesFromFeed(Feed).Result); TaskList.Add(T); } var Results = await Task.WhenAll(TaskList); // Filter the not null results - on the balance of probabilities, we'll still get more than 7 results. var ReturnList = Results.SelectMany(s => TaskList.Where(w => w.Result != null).SelectMany(z => z.Result).OrderByDescending(o => o.PublishDate)).Take(articlesToTake); return ReturnList; } private async static Task<IEnumerable<SyndicationItem>> GetLatestArticlesFromFeed(string feedURL) { // We're only accepting XML based feeds, so create an XML reader: try { XmlReader Reader = XmlReader.Create(feedURL); SyndicationFeed Feed = SyndicationFeed.Load(Reader); Reader.Close(); return Feed.Items.OrderByDescending(o => o.PublishDate).Take(5); } catch (Exception ex) { return null; } } }

It took me a while to wrap my head around, as I was forgetting to define the result type of the task I was kicking off, but thankfully I stumbled across this question this morning, which helped everything fall nicely into place.

I feel a bit cheeky answering my own question, but on balance I think this is a nice, tidy balance between the proposed answers and it certainly seems functional. I'll add some hardening and comments, and of course if anyone has feedback I'll receive it gratefully.

Thanks! Ash

更多推荐

本文发布于:2023-07-15 05:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1110600.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:构建一个   系列   IEnumerable   Constructing   collection

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!