简体   繁体   中英

Return item 1 to 3 and 4 to 6 and 7 to 9 in a grouped object with LINQ

I have this collection:

[bla1,blubb2,hello3,salve4,adios5,bye6,mucha7,arrividerci8,bonsoir9,hello10,bah11]

I would like to return a collection of T where T has a List with these 3 strings max.

bla1, blubb2, hello3,

salve4, adios5, bye6

mucha7, arrividerci8,bonsoir9

hello10,bah11

These are no 4 objects each having a list with max. 3 items

It looks like you want:

List<List<string>> groups = inputList.Select((e, idx) => new { Item = e, Idx = idx })
    .GroupBy(p => p.Idx / 3)
    .Select(grp => grp.Select(p => p.Item).ToList())
    .ToList();
string[] arr = new[] { "bla1", "blubb2", "hello3", "salve4", "adios5", "bye6", "mucha7", "arrividerci8", "bonsoir9", "hello10", "bah11" };
int cnt=0;
var lists = arr.GroupBy(x => cnt++ / 3)
                .Select(g => g.ToList())
                .ToList();

You can use MoreLINQ (avalable from NuGet) extension Batch :

string[] source = { "bla1", "blubb2", "hello3", "salve4", "adios5" };
IEnumerable<IEnumerable<string>> result = source.Batch(3);

This extension batches source sequence into sized buckets.

If you don't want to use MoreLINQ library, you can use just their implementation of Batch extension or solution by Timothy.

(Use Sergey's answer if you don't mind the MoreLINQ dependency.)

Extension Method

public static IEnumerable<List<T>> GroupSequential<T>(
    this IEnumerable<T> source, int groupSize, bool includePartialGroups = true)
{
    if (groupSize < 1)
    {
        throw new ArgumentOutOfRangeException(
            "groupSize", groupSize, "Must have groupSize >= 1.");
    }
    var group = new List<T>(groupSize);
    foreach (var item in source)
    {
        group.Add(item);
        if (group.Count == groupSize)
        {
            yield return group;
            group = new List<T>(groupSize);
        }
    }
    if (group.Any() && (includePartialGroups || group.Count == groupSize))
    {
        yield return group;
    }
}

Usage

IEnumerable<string> values = ...;
IEnumerable<List<string>> groups = values.GroupSequential(3);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM