【问题标题】:Is there a way to fill a collection using a LINQ expression?有没有办法使用 LINQ 表达式填充集合?
【发布时间】:2010-01-09 05:05:13
【问题描述】:

LINQ 的一大优点是,它允许您获取与集合相关的信息,而无需手动编写代码来遍历集合。 有没有办法使用 LINQ 填充集合,从而避免编写循环?


例如,假设我有以下代码,它适用于从 1 到 10 的数字范围:

public static void LinqTest()
{
    List<int> intList = new List<int>();
    for (int i = 1; i <= 10; i++)     //  <==== I'm having to use a for loop
        intList.Add(i);               //        here to populate the List.
    int intSum = intList.Sum();
    int intSumOdds = intList.Where(x => x % 2 == 1).Sum();
    double intAverage = intList.Average();
    Console.WriteLine("Sum is {0}\tSum of Odds is {1}\tAverage is {2}", 
        intSum, intSumOdds, intAverage);
}

LINQ 已经替换了 检索 数据信息所需的 for 循环。我很好奇 LINQ 是否可以用来替换 填充 数据的for 循环。有没有办法用LINQ来代替下面两行代码?

    for (int i = 1; i <= 10; i++)
        intList.Add(i);

【问题讨论】:

    标签: c# .net linq iteration


    【解决方案1】:

    正如其他人所说,您可以使用Enumerable.Range(int, int) 生成返回为IEnumerable&lt;int&gt; 的整数序列。

    虽然您可以通过已经建议的各种方式将结果转换为List&lt;int&gt;,但只有在您确实需要List&lt;T&gt; 时才应该这样做。

    在这种情况下,没有必要这样做。你的函数可以重写如下:

    IEnumerable<int> intList = Enumerable.Range(1, 10);
    int intSum = intList.Sum();
    int intSumOdds = intList.Where(x => x % 2 == 1).Sum();
    double intAverage = intList.Average();
    

    这更有效,因为Enumerable.Range 返回的序列是在枚举时“延迟”生成的。另一方面,当序列转换为List&lt;int&gt; 时,所有值必须同时保存在内存中。

    【讨论】:

    • +1 用于避免使用 List 支持 IEnumerable
    【解决方案2】:

    您不会使用 LINQ 填充现有列表;您将创建一个 Enumerable 然后将其转换为列表。在这种情况下,它很简单

    IList<int> intList = Enumerable.Range(1, 10).ToList();
    

    【讨论】:

    • +1 很好,但是如果您想匹配问题中的示例,您将落后一分。诠释 i = 1;我
    • +1 好答案。小备注:运行时完全相同,可能会快一点,因为它是本机编译的。好吧,使用 JIT 编译器甚至不确定。
    • Enumerable 类是 System.Linq 的一部分,这是否意味着我们仍在使用 LINQ?
    • 嗯,LINQ 实际上是两件事:一组用于生成和使用枚举的方法,以及用于使用这些方法的特殊语法。在这种情况下,我们使用的是前者,而不是后者。如果您想使用特殊语法,我想您可能会使用(from Enumerable.Range(1, 10)).ToList(),尽管我看不到优势。
    【解决方案3】:

    我认为您在特定情况下寻找的是Enumerable.Range()。从那里,如果您愿意,可以使用 Wheres 等过滤列表。例如,如果我想要所有 2 的幂小于 100 的数字,我会做类似Enumerable.Range(1,100).Where(i =&gt; i * i &lt; 100) 的操作。这在像 Haskell 这样的函数式语言中很常见,类似的东西是这样的:filter (\i -&gt; i * i &lt; 100) [1..100]

    替换函数的具体示例:

    Enumerable.Range(1,10).Where(x => x%2 == 1).Sum();
    //add separate sum and averages here
    

    【讨论】:

    • 这是有道理的。如果 Sum 不是列表,我当时不确定是否需要一堆参数。
    【解决方案4】:

    List&lt;T&gt; 有一个以IEnumerable&lt;T&gt; 为参数的构造函数。您可以使用Enumerable.Range 生成数字。

    List<int> values = new List<int>(Enumerable.Range(1, 10));
    

    如果要将值添加到先前构造的List&lt;T&gt;,可以以相同的方式使用List&lt;T&gt;.AddRange

    values.AddRange(Enumerable.Range(1, 10));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多