Split List into Sublists With Linq

Split List into Sublists with LINQ

Try the following code.

public static List<List<T>> Split<T>(IList<T> source)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / 3)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}

The idea is to first group the elements by indexes. Dividing by three has the effect of grouping them into groups of 3. Then convert each group to a list and the IEnumerable of List to a List of Lists

Split a collection into `n` parts with LINQ?

A pure linq and the simplest solution is as shown below.

static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts)
{
int i = 0;
var splits = from item in list
group item by i++ % parts into part
select part.AsEnumerable();
return splits;
}
}

How to Split a object list into sublists grouping by elements(dateTime and String) C#

Here is my solution using Linq.Aggregate:

private void button_Click(object sender, EventArgs e)
{
List<Identity> listOfIdentity = new List<Identity>()
{
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.550"), PcName="Test3"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.300"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.350"), PcName="Test2"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.400"), PcName="Test2"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.200"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.500"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.250"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.450"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.150"), PcName="Test1"}
};
List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList(); // here i order by time and then pc name
var result = sortedIdentity.Skip(1).Aggregate(new List<List<Identity>> { new List<Identity> { sortedIdentity[0] } }, (lists, curr) =>
{
if (curr.PcName == lists.Last()[0].PcName)
lists.Last().Add(curr);
else
lists.Add(new List<Identity> { curr });
return lists;
});
}

It iterates over each element and checks, if it's PcName is the same as previous. If it is, it goes on the same list, else new list is created with this element.


EDIT: More elegant solution suggested by Matt.G

    List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList();
var result = sortedIdentity.Aggregate(new List<List<Identity>>(), (lists, curr) =>
{
if (curr.PcName == lists.LastOrDefault()?.FirstOrDefault()?.PcName)
lists.Last().Add(curr);
else
lists.Add(new List<Identity> { curr });
return lists;
});

Split a List into smaller lists of N size

public static List<List<float[]>> SplitList(List<float[]> locations, int nSize=30)  
{
var list = new List<List<float[]>>();

for (int i = 0; i < locations.Count; i += nSize)
{
list.Add(locations.GetRange(i, Math.Min(nSize, locations.Count - i)));
}

return list;
}

Generic version:

public static IEnumerable<List<T>> SplitList<T>(List<T> locations, int nSize=30)  
{
for (int i = 0; i < locations.Count; i += nSize)
{
yield return locations.GetRange(i, Math.Min(nSize, locations.Count - i));
}
}

Split list into sublists based on a value of a certain property?

You need to make a grouping by year like this:

eventsList.GroupBy(x => x.Year)

So later you will be able to iterate through result of code above:

foreach (var eventsInYear in eventsList.GroupBy(x => x.Year))
{
// eventsInYear.Key - year
// eventsInYear - collection of events in that year
}

How to Split a list into sublists grouping by elements

Just use GroupBy and create an anonymous class with the properties you want to group on.

var result = yourList.GroupBy(x => new { x.ItemA, x.ItemB })
.Select(grp => grp.ToList())
.ToList();


Related Topics



Leave a reply



Submit