【问题标题】:Select lists from lists with linq使用 linq 从列表中选择列表
【发布时间】:2014-04-02 22:54:20
【问题描述】:

我有一个包含 x 个项目的列表。我希望得到一个基于数字而不是属性对该列表进行分组的结果。

例如。

我有一个包含 8 个项目的列表。我想将它们按 3 分组。 我想得到一个包含三个列表的列表,其中前两个列表包含三个项目,最后一个列表包含其余两个。

我想要一个比这更优雅的解决方案:

private static List<List<string>> GroupBy(List<string> pages, int groupSize)
{
    var result = new List<List<TrimlinePage>>();
    while (!(result.Count != 0 && result.Last().Count % 3 > 0))
    {
        int skip = result.Count*groupSize;
        var group = pages.Skip(skip).Take(groupSize).ToList();
        result.Add(group);
    }
    return result;
}

【问题讨论】:

    标签: c# linq list


    【解决方案1】:

    您可以使用整数除法技巧:

    List<List<string>> lists = pages
        .Select((str, index) => new { str, index }) 
        .GroupBy(x => x.index / groupSize)
        .Select(g => g.Select(x => x.str).ToList())
        .ToList();
    

    例子:

    int groupSize = 3;
    var pages = new List<string> { "A", "B", "C", "D", "E", "F", "G" };
    List<List<string>> lists = pages
        .Select((str, index) => new { str, index })
        .GroupBy(x => x.index / groupSize)
        .Select(g => g.Select(x => x.str).ToList())
        .ToList();
    

    结果:

    foreach(var list in lists)
        Console.WriteLine(string.Join(",", list));
    

    输出:

    A,B,C
    D,E,F
    G
    

    因此,此方法将为您提供具有指定最大大小的列表,在本例中为 3。如果您想确保始终获得三个列表,则需要使用 % 而不是 /

    List<List<string>> lists = pages
        .Select((str, index) => new { str, index }) 
        .GroupBy(x => x.index % groupSize)
        .Select(g => g.Select(x => x.str).ToList())
        .ToList();
    

    【讨论】:

      【解决方案2】:

      试试这个:

      var list = Enumerable.Range(1,100);
      var query = list
                    .Select((x, i) => new {x, i})
                    .GroupBy(v => v.i / 3).Select(g => g.Select(v =>v.x.ToList()))
                    .ToList();
      

      【讨论】:

        【解决方案3】:

        这是一个使用副作用的简单解决方案(通常不鼓励):

        private static List<List<string>> GroupBy(List<string> pages, int groupSize)
        {
            var i = 0;
            return pages.GroupBy(p => i++ / 3, (k, g) => g.ToList()).ToList();
        }
        

        或者如果你想避免依赖副作用,你可以使用这个:

        private static List<List<string>> GroupBy(List<string> pages, int groupSize)
        {
            return pages.Select(p => new { p, i })
                        .GroupBy(x => x.i / 3)
                        .Select(g => g.Select(x => x.p).ToList())
                        .ToList();
        }
        

        【讨论】:

          【解决方案4】:

          LINQ 不是最好的解决方案。良好的旧索引通常更具可读性和效率。

          private static List<List<T>> GroupBy(List<T> pages, int groupSize)
          {
              var result = new List<List<T>>();
              List<T> l;
              for (int i=0; i < pages.Count; i++)
              {
                  if (i%groupSize == 0)
                  {
                      l = new List<T>();
                      result.Add(l);
                  }
                  l.Add(pages[i]);
              }
              return result;
          }
          

          【讨论】:

            【解决方案5】:

            您还可以查看包含Partition 方法的morelinq

            它可以通过 NuGet 获得。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多