c# - 缓存 LINQ 查询 - IEnumerable.Skip()

标签 c# linq

考虑以下代码

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;

关于c# - 缓存 LINQ 查询 - IEnumerable.Skip(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51417755/

相关文章:

c# - 导出到 Excel 给我复选框而不是字符串

c# - 异步填充c#字典

c# - Entity Framework 查询中 && 和 where 条件的区别

C# 到 C++ 多态性

c# - Windows Phone 的复选框

c# - ASP.NET MVC 中的自定义安全方案

c# - 使用导入的架构编译 XmlSchemaSet

c# - 如何访问斯坦福解析器返回的依赖树和选区树中的各个节点?

c# - 为什么在第二种情况下不执行简单的 linq 命令?

mysql - 在具有多个条件的 DataTable 中选择重复值