【问题标题】:LINQ queries on possibly infinite lists对可能无限列表的 LINQ 查询
【发布时间】:2009-03-30 00:37:40
【问题描述】:

我目前正在做一些 Project Euler 问题,早期的问题通常涉及斐波那契数或素数之类的问题。对它们进行迭代似乎很适合 LINQ,至少在代码的可读性和感知“优雅”方面是这样(我正在尝试在可能且适用的情况下使用特定于语言的特性来感受这些语言)。

我现在的问题是,如果我只需要一组达到一定限度的数字,我应该如何最好地表达这一点?目前我已经在迭代器中硬编码了各自的限制,但我真的希望枚举器返回列表,直到外部的东西决定不再查询它,因为它超过了一定的限制。所以基本上我有一个潜在的无限迭代器,但我只从中获取一组有限的数字。我知道这样的事情在函数式语言中是微不足道的,但我想知道 C# 是否也允许这样做。我唯一的另一个想法是拥有一个迭代器 Primes(long),它返回某个限制的素数,对于其他序列也是如此。

有什么想法吗?

【问题讨论】:

    标签: c# linq ienumerable


    【解决方案1】:

    大多数 LINQ 方法(Enumerable 类)都是惰性的。因此,例如,没有任何问题:

    var squares = Enumerable.Range(0, Int32.MaxValue).Select(x=>x*x);
    

    可以使用 Take 方法来限制结果:

    var 10squares = squares.Take(10);
    
    var smallSquares = squares.TakeWhile(x => x < 10000);
    

    编辑:您需要避免的事情是“延迟”返回但必须消耗整个可枚举来产生结果的函数。例如,分组或排序:

    var oddsAndEvens = Enumerable.Range(0, Int32.MaxValue)
                                 .GroupBy(x => x % 2 == 0);
    foreach (var item in oddsAndEvens) {
      Console.WriteLine(item.Key);
    }
    

    (这可能会给你一个 32 位的 OutOfMemoryExeption。)

    【讨论】:

    • 啊,好吧,到目前为止还不知道 TakeWhile。我只是认为使用 Where 来选择我想要的数字是行不通的,因为 LINQ 不知道数字正在增加,例如。听起来不错,确实:)
    • +1,很好的总结。我也试着对这个话题做一点阐述:blog.casualdev.net/2009/10/linq-and-infinite-enumerations.html
    猜你喜欢
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多