C# Linq每次迭代选择5个项目

C# Linq每次迭代选择5个项目,c#,linq,C#,Linq,Linq根据我们的枚举器每次选择5项 我们的列表,例如“列表”有100项, 要浏览列表,并在每次迭代中选择5项 示例代码,我们希望将其更改为所需的结果: theList = dt.AsEnumerable() .Select(row => new CustItem { Name = row.Field<string>("tName"), Title =

Linq根据我们的枚举器每次选择5项

我们的列表,例如“列表”有100项, 要浏览列表,并在每次迭代中选择5项

示例代码,我们希望将其更改为所需的结果:

        theList = dt.AsEnumerable()
            .Select(row => new CustItem
            {
                Name = row.Field<string>("tName"),
                Title = row.Field<string>("tTitle"),
            }).ToList();
theList=dt.AsEnumerable()
.选择(行=>new CustItem
{
名称=行字段(“tName”),
标题=行字段(“tTitle”),
}).ToList();
我们应该在循环中迭代它,每次对选定的5项进行处理,或者将其传递给其他方法:

类似的:

for (int i=0; i < 20 ; i++)
for(int i=0;i<20;i++)

我想在
linq select
语句上使用
“I”
枚举器,并进行多重运算以形成新结果集的边界。

听起来您希望运算符来自:

for(int i=0;i<20;i++)
{
var fiveitems=list.Skip(i*5).Take(5);
}

您也可以通过利用整数算法和
GroupBy
方法,使用纯linq执行此操作:

int blockSize = 5;
var group = theList.Select((x, index) => new { x, index })
                   .GroupBy(x => x.index / blockSize, y => y.x);

foreach (var block in group)
{
    // "block" will be an instance of IEnumerable<T>
    ...
}
int blockSize=5;
var group=theList.Select((x,index)=>new{x,index})
.GroupBy(x=>x.index/blockSize,y=>y.x);
foreach(组中的var块)
{
//“block”将是IEnumerable的一个实例
...
}
这种方法有许多优点,但并不一定立即显现出来:

  • 执行是延迟的,因此在使用条件处理时效率很高
  • 您不需要知道集合的长度,因此避免了多次枚举,同时通常比其他方法更简洁

以下静态扩展方法将使将列表拆分为具有特定批量大小的多个列表成为一个简单的过程

    public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items, int noOfItemsPerBatch)
    {
        decimal iterations = items.Count() / noOfItemsPerBatch;

        var roundedIterations = (int)Math.Ceiling(iterations);

        var batches = new List<IEnumerable<T>>();

        for (int i = 0; i < roundedIterations; i++)
        {
            var newBatch = items.Skip(i * noOfItemsPerBatch).Take(noOfItemsPerBatch).ToArray();
            batches.Add(newBatch);
        }

        return batches;
    }
试试这个:

 for (int i = 0; i < list.Count; i = i + 5) {
                var fiveitems = list.Skip(i).Take(5);
                foreach(var item in fiveitems)
                {

                }
            }
for(int i=0;i
Hi Jon,看起来很有趣,但需要订购,是吗?Hi Jon,你能告诉我Govind的方法有什么问题吗?@Asif:嗯,这会在源代码上重复多次,这可能不太理想。如果这真的是一个
列表
,那没关系,但是如果这是你不想放进内存的东西(例如,你正在从文本文件中流行),你就不想为每个批次重新读取文件。你可以使用Jon的“SmartEnumerable”扩展名:@Sypress:不,目前没有“批次号”的指示器,虽然正如Matthew所说,如果你想的话,你可以使用SmartEnumerable。谢谢,它也会有帮助,+1,你能告诉我一些关于x,y,blocksize和索引的信息吗?索引似乎是集合的起点,其他的呢?这里还有一个问题,我们需要知道我们选择的可枚举列表中项目的索引,这里应该是“组”。我还没有尝试过这种方法。我使用的
Select
重载采用了两个参数
Func
,其中的参数是项(与普通的
Select
)及其索引。然后,代码将其投影到包含原始项及其索引的新数据类型中。
GroupBy
很简单,因为整数除法总是向下舍入,
index/blocksize
对于块中的每个项目都是相同的(即“0/5==1/5==2/5==3/5==4/5”)。我的最后一步,
y=>y.x
只是再次提取原始项,但如果您想保留索引,请不要包含最后的lambda。这是我找到的最佳答案!谢谢这两个链接可能会帮助你…这是如何改进Govind的答案的?这一个考虑到了数组的大小。这对大列表来说是不好的,因为它看起来是二次的。我应该
i
不以5为单位递增吗?目前,它将执行5个批次,但相同的项目将在4个不同批次中出现4次?
    public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items, int noOfItemsPerBatch)
    {
        decimal iterations = items.Count() / noOfItemsPerBatch;

        var roundedIterations = (int)Math.Ceiling(iterations);

        var batches = new List<IEnumerable<T>>();

        for (int i = 0; i < roundedIterations; i++)
        {
            var newBatch = items.Skip(i * noOfItemsPerBatch).Take(noOfItemsPerBatch).ToArray();
            batches.Add(newBatch);
        }

        return batches;
    }
var items = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var batchedItems = items.Batch(4);

Assert.AreEqual(batchedItems.Count() == 3);
Assert.AreEqual(batchedItems[0].Count() == 4);
Assert.AreEqual(batchedItems[1].Count() == 4);
Assert.AreEqual(batchedItems[2].Count() == 2);
 for (int i = 0; i < list.Count; i = i + 5) {
                var fiveitems = list.Skip(i).Take(5);
                foreach(var item in fiveitems)
                {

                }
            }