LINQ方法将集合分组到具有指定数量元素的子组

时间:2010-07-04 20:11:38

标签: c# linq .net-3.5 group-by

是否存在LINQ方法将给定集合分组到具有指定数量的元素的子组中,这类似于Scala的grouped方法。 例如
在Scala中,List(89, 67, 34, 11, 34).grouped(2)给出List(List(89, 67), List(34, 11), List(34))

如果不存在这样的方法,那么LINQ的方法是什么?

3 个答案:

答案 0 :(得分:2)

您可以尝试使用this answer中显示的方法similar question

public static class GroupingExtension
{
    public static IEnumerable<IEnumerable<T>> Grouped<T>(
        this IEnumerable<T> input,
        int groupCount)
    {
        if (input == null) throw new ArgumentException("input");
        if (groupCount < 1) throw new ArgumentException("groupCount");

        IEnumerator<T> e = input.GetEnumerator();

        while (true)
        {
            List<T> l = new List<T>();
            for (int n = 0; n < groupCount; ++n)
            {
                if (!e.MoveNext())
                {
                    if (n != 0)
                    {
                        yield return l;
                    }
                    yield break;
                }
                l.Add(e.Current);
            }
            yield return l;
        }
    }
}

像这样使用:

List<int> l = new List<int>{89, 67, 34, 11, 34};
foreach (IEnumerable<int> group in l.Grouped(2)) {
    string s = string.Join(", ", group.Select(x => x.ToString()).ToArray());
    Console.WriteLine(s);
}

结果:

89, 67
34, 11
34

答案 1 :(得分:2)

这是一个似乎有一些示例代码可以做你想要的网站: http://www.chinhdo.com/20080515/chunking/

所以你可以做的是采用这种方法并创建一个扩展方法。

扩展方法示例:

static class ListExtension
{
    public static List<List<T>> BreakIntoChunks<T>(this List<T> list, int chunkSize)
    {
        if (chunkSize <= 0)
        {
            throw new ArgumentException("chunkSize must be greater than 0.");
        }

        List<List<T>> retVal = new List<List<T>>();

        while (list.Count > 0)
        {
            int count = list.Count > chunkSize ? chunkSize : list.Count;
            retVal.Add(list.GetRange(0, count));
            list.RemoveRange(0, count);
        }

        return retVal;
    }
}

答案 2 :(得分:2)

是的,你可以。但你可以争论它是否非常漂亮......

  Int64[] aValues = new Int64[] { 1, 2, 3, 4, 5, 6 };
  var result = aValues
          .Select( ( x, y ) => new KeyValuePair<Int64, Int32>( x, y ) )
          .GroupBy( x => x.Value / 2 )
          .Select( x => x.Select( y => y.Key ).ToList() ).ToList();

工作原理:

从原始集合中选择 x y ,其中 x 是实际值, y 是给定集合中的索引。然后按索引的整数分割分组和所需的分组长度(在此示例中 2 )。

按整数分组进行分组将向上舍入到更低 - 所以 0/2 = 0 1/2 = 0 等等,这将为我们提供所需的分组类别价值。这就是我们在这里分组的内容。

对于结果,仅选择在列表中分组的值,并将它们作为列表集合返回。