【问题标题】:Remove Multiple Elements From List<T>从 List<T> 中删除多个元素
【发布时间】:2012-11-09 23:23:58
【问题描述】:

我想知道,是否有一种优雅的方法可以从通用集合中删除多个项目(在我的例子中是 List&lt;T&gt;),而无需执行诸如在 LINQ 查询中指定谓词以查找要删除的项目之类的操作?

我正在做一些批处理,其中我正在用需要处理的Record 对象类型填充List&lt;T&gt;。该处理以将每个对象插入数据库而结束。我不想构建列表,然后遍历每个单独的成员并处理/插入它,而是希望使用列表中的 N 项目组执行事务批量插入,因为它的资源密集度较低(其中 N 代表 @987654326 @ 我可以放入配置文件或等效文件中)。

我想做类似的事情:

public void ProcessRecords()
{
    // list of Records will be a collection of List<Record>
    var listOfRecords = GetListOfRecordsFromDb( _connectionString );
    var batchSize = Convert.ToInt32( ConfigurationManager.AppSettings["BatchSize"] );

    do
    {
       var recordSubset = listOfRecords.Take(batchSize);
       DoProcessingStuffThatHappensBeforeInsert( recordSubset );

       InsertBatchOfRecords( recordSubset );

       // now I want to remove the objects added to recordSubset from the original list
       // the size of listOfRecords afterwards should be listOfRecords.Count - batchSize
    } while( listOfRecords.Any() )
}

我正在寻找一种一次性完成所有操作的方法,而不是遍历子集并以这种方式删除项目,例如:

foreach(Record rec in recordSubset)
{
   if( listOfRecords.Contains(rec) ) 
   { 
      listOfRecords.Remove(rec);
   }
}

我正在考虑使用List.RemoveRange( batchSize ),但想先获得一些 StackOverflow 反馈 :) 您使用什么方法来最大限度地提高 C# 中批处理算法的效率?

非常感谢任何帮助/建议/提示!

【问题讨论】:

  • Record 是什么类?是自定义类还是IDataRecord
  • 看起来你抓取的记录都在列表的开头。你为什么不改用Queue&lt;T&gt;
  • Record 是我用来说明这个概念的假设自定义类。

标签: c# list collections batch-processing generic-collections


【解决方案1】:

有扩展方法

public static IEnumerable<List<T>> ToBatches<T>(this List<T> list, int batchSize)
{
    int index = 0;
    List<T> batch = new List<T>(batchSize);

    foreach (T item in list)
    {
        batch.Add(item);    
        index++;

        if (index == batchSize)
        {
            index = 0;                
            yield return batch;
            batch = new List<T>(batchSize);
        }
    }

    yield return batch;
}

您可以将输入序列拆分为批次:

foreach(var batch in listOfRecords.ToBatches(batchSize))
{
   DoProcessingStuffThatHappensBeforeInsert(batch);
   InsertBatchOfRecords(batch);
}

【讨论】:

  • 我认为最初创建批量大小的列表是个好主意。
  • @HamletHakobyan 完全同意
【解决方案2】:

MoreLINQ 有一个Batch extension method 可以让你打电话

var listOfRecords = GetListOfRecordsFromDb( _connectionString );
var batchSize = Convert.ToInt32( ConfigurationManager.AppSettings["BatchSize"] );

foreach(var batch in listOfRecords.Batch(batchSize))
{
   DoProcessingStuffThatHappensBeforeInsert(batch);
   InsertBatchOfRecords(batch);
}

您无需费心listOfRecords 中取出东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 2010-10-11
    • 1970-01-01
    • 2023-03-25
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    相关资源
    最近更新 更多