c# – 缓存LINQ查询 – IEnumerable.Skip()
发布时间:2020-12-15 22:52:15 所属栏目:百科 来源:网络整理
导读:请考虑以下代码 IEnumerableItems remainingItems = Itemsvar results = new ListListItems();var counter = 0;while (remainingItems.Any()){ var result = new ListItem(); result.AddRange(remainingItems.TakeWhile(x = somePredicate(x,counter)); resu
请考虑以下代码
IEnumerable<Items> remainingItems = Items var results = new List<List<Items>>(); var counter = 0; while (remainingItems.Any()) { var result = new List<Item>(); result.AddRange(remainingItems.TakeWhile(x => somePredicate(x,counter)); results.Add(result); remainingItems = remainingItems.Skip(result.Count); counter++; } 如果不清楚发生了什么,我会采用Ienumerable,并迭代它直到谓词失败,将所有这些项放入一堆,然后继续迭代其余项,直到下一个谓词失败,并将所有这些在一堆.冲洗,洗涤,重复. 现在我要关注的是Ienumerable.Skip() 由于它使用延迟执行,这意味着我必须遍历我在每个循环中已经跳过的所有元素. 我可以使用ToList()来强制它进行评估,但是它需要迭代所有剩余的项目来执行此操作,这同样糟糕. 所以我真正需要的是一个IEnumerable,它会急切地跳过它,然后存储我们最后的第一点,从那里继续.所以我需要一些功能,如: IEnumerable.SkipAndCache(n)允许我从第n项开始访问IEnumerator. 有任何想法吗? 解决方法
您可以使用
MoreLinq.有一个名为Memoize的实验函数可以懒惰地缓存序列.所以代码看起来像这样:
while (remainingItems.Any()) { var result = new List<Item>(); result.AddRange(remainingItems.TakeWhile(x => somePredicate(x,counter)); results.Add(result); remainingItems = remainingItems.Skip(result.Count).Memoize(); counter++; } 这里的结果将不会实现,因为它仍然是懒惰的评估: remainingItems = remainingItems.Skip(result.Count).Memoize(); 这里将对remainingItems序列进行求值和缓存(迭代器不会遍历ToList中的所有元素): remainingItems.Any() 这里将使用缓存: result.AddRange(remainingItems.TakeWhile(x => somePredicate(x,counter)); 要使用此方法,您需要添加: using MoreLinq.Experimental; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |