我喜欢将所有数据选择为不可预测数量的四元包(每个包包含四个项目),例如:
foreach(var quaternary in myEnauerable.ToQuaternaryPackages())
{
//Whatever (Like: l=page.Add(new List()))
foreach(var item in quaternary)
{
//Whatever (Like: l.Add(item))
}
}
我认为您正在寻找类似MoreLINQ Batch
方法的东西:
foreach (var batch in myEnumerable.Batch(4))
{
foreach (var item in batch)
{
// ...
}
}
请注意,如果总数不能被 4 整除,则最终批次将少于 4 个项目。(例如,如果最初有 14 个项目,您将获得三批 4,然后是一批 2。)
您可以将 MoreLINQ 作为一个大型 Nuget 包或单个包(例如package)获取。Batch
首先,制作一个简单的 Batch 方法(将其放在静态类中):
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
List<T> temp = new List<T>();
foreach (T item in source)
{
temp.Add(item);
if (temp.Count == batchSize)
{
yield return temp.Select(n => n);
temp.Clear();
}
}
if (temp.Any())
{
yield return temp.Select(n => n);
}
}
然后像这样使用它:
foreach(var quaternary in myEnauerable.Batch(4))
{
//Whatever (Like: l=page.Add(new List()))
foreach(var item in quaternary)
{
//Whatever (Like: l.Add(item))
}
}
无耻地从 Troy Goode 的 PagedList 库中窃取:https ://github.com/TroyGoode/PagedList/blob/master/src/PagedList/PagedListExtensions.cs
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> superset, int pageSize)
{
if (superset.Count() < pageSize)
yield return superset;
else
{
var numberOfPages = Math.Ceiling(superset.Count() / (double)pageSize);
for (var i = 0; i < numberOfPages; i++)
yield return superset.Skip(pageSize * i).Take(pageSize);
}
}
像这样使用它:
var result=myEnumerable.Partition(4);
如果您确实需要结果不可预测(即随机),我建议使用以下算法:
对于第二部分,已经提供了许多很好的答案。对于第一部分,Eric Lippert 有一个关于使用 LINQ 创建排列的非常深入的系列。
使用 linq 非常简单:
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
for (int i = 0; i < source.Count(); i+=batchSize)
{
yield return source.Skip(i).Take(batchSize);
}
}
这样,您可以按项目的 batchSize 拆分列表,并且如果项目的数量不能被批次大小整除,则最后一次迭代将产生其余的可枚举。