可能重複:
How can I split an IEnumerable<String> into groups of IEnumerable<string>使用linq將列表<t>劃分成n個長度大的列表<t>?
我有,我想打入的10
組如果我有一個對象列表
List<Person> allPendingPersons
長度爲m的
。
在LINQ中有沒有一種優雅的方式將allPendingPersons分解爲一個或多個List對象,所有對象都有最多10個人?
可能重複:
How can I split an IEnumerable<String> into groups of IEnumerable<string>使用linq將列表<t>劃分成n個長度大的列表<t>?
我有,我想打入的10
組如果我有一個對象列表
List<Person> allPendingPersons
長度爲m的
。
在LINQ中有沒有一種優雅的方式將allPendingPersons分解爲一個或多個List對象,所有對象都有最多10個人?
var groups = allPendingPersons.Select((p, index) => new {p,index})
.GroupBy(a =>a.index/10);
如果你想處理IGrouping<,>
。如果您正在尋找名單>回你可以嘗試
var listOfLists = allPendingPersons.Select((p, index) => new {p, index})
.GroupBy(a => a.index/10)
.Select((grp => grp.Select(g => g.p).ToList()))
.ToList();
您可以編寫自己的擴展方法:
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> sequence, int size) {
List<T> partition = new List<T>(size);
foreach(var item in sequence) {
partition.Add(item);
if (partition.Count == size) {
yield return partition;
partition = new List<T>(size);
}
}
if (partition.Count > 0)
yield return partition;
}
我在我的博客explored this in more depth。
這不是最有效的技術,但是這會產生一個IEnumerable<IEnumerable<Person>>
序列,包含十個元素每個內部序列:
var query = allPendingPersons.Select((x, i) => new { Value = x, Group = i/10 })
.GroupBy(x => x.Group,
(k, g) => g.Select(x => x.Value));
如果結果確實需要一個列表中,列表,而不是一個簡單的順序,那麼你可以創建一個List<List<Person>>
通過,而不是在幾個ToList
來電補充說:
var query = allPendingPersons.Select((x, i) => new { Value = x, Group = i/10 })
.GroupBy(x => x.Group,
(k, g) => g.Select(x => x.Value).ToList())
.ToList();
您可以通過編寫'x => x.Value'而不是'(k,g)=> g.Select(x => x)來簡化您的第一個版本。值)'。 – 2011-03-07 03:40:13
嘗試迭代器塊:
public static IEnumerable<List<Person>> AsGroups(this List<Person> persons)
{
var buf = new List<Person>(10);
for (int i = 0; i<persons.Count i++;)
{
buf.Add(persons[i]);
if (i%10 == 0 && buf.Count > 0)
{
yield return buf;
buf = new List<Person>(10);
}
}
yield return buf;
}
的Reactive Extensions for .NET (Rx)有一個擴展方法,它不正是你想要什麼:
var buffered = allPendingPersons.BufferWithCount(10);
如果你想要做使用LINQ,你可以做到這一點:
var buffered =
allPendingPersons
.Select((p, i) => new { Group = i/10, Person = p })
.GroupBy(x => x.Group, x => x.Person)
.Select(g => g.ToArray());
這些應該有一定的幫助。
How can I split an IEnumerable<String> into groups of IEnumerable<string>
Divide a large IEnumerable into smaller IEnumerable of a fix amount of item
Can I improve these Pagination extension methods?
Get groups of 4 elements from name value list using LINQ in C#
LINQ: Get min and max values of sequence of numbers divided into subsequences
LINQ Partition List into Lists of 8 members
一個非常普遍的回答是檢查出喬恩斯基特的MoreLinq,特別是Batch
功能,它不僅做了你是什麼要求,但也讓你指定一個返回選擇器!
+1 MoreLink的'Batch',[見源代碼](https://github.com/morelinq/MoreLINQ/blob/master/MoreLinq/Batch.cs) – lagerone 2016-09-06 08:26:20
是否有LINQ
的elegant way一種優雅的方式是不是很高性能。這裏是一個更高性能的方式...
public static List<List<T>> Chunk<T>(
this List<T> theList,
int chunkSize
)
{
if (!theList.Any())
{
return new List<List<T>>();
}
List<List<T>> result = new List<List<T>>();
List<T> currentList = new List<T>();
result.Add(currentList);
int i = 0;
foreach(T item in theList)
{
if (i >= chunkSize)
{
i = 0;
currentList = new List<T>();
result.Add(currentList);
}
i += 1;
currentList.Add(item);
}
return result;
}
您可以比編寫迭代器更高效。看到我的答案。 – SLaks 2011-03-08 16:26:17
不是最高效的,GroupBy會緩衝所有元素並構建查找。因此,內存+ CPU開銷+不是蒸汽解決方案 – 2015-04-22 23:52:43