在迭代期间将对象添加到现有列表

Posted

技术标签:

【中文标题】在迭代期间将对象添加到现有列表【英文标题】:Adding an object to an existing list during iteration 【发布时间】:2021-12-29 04:23:06 【问题描述】:

我有一个包含 5 个对象的列表。

List<ObjA> listA = new List<ObjA>();

我有一个要求,在遍历列表时,如果满足某些条件,我需要创建当前对象的副本并修改一个属性并将其添加回 listA。 我可以创建一个单独的列表,在 for 循环之后,我可以将它添加到 listA 但有没有更好的方法来实现这一点?

foreach(var a in listA)

  //if(a.somecondition is true)
  // create a clone of 'a' and add it to listA

【问题讨论】:

创建原始列表的副本;遍历一个版本并填充另一个版本。 这能回答你的问题吗? How to generate duplicate items in a list using LINQ? 创建一个单独的列表然后将它们全部添加有什么问题?它可能是最易读的代码。 【参考方案1】:

既然你有一个列表,你可以按索引迭代:

// save the length before we iterate so that we don't iterate into new items
int length = listA.Count; 

// loop from 0 to the original length
for (int i = 0; i < length; ++i)

    var a = listA[i];
    if (a.somecondition)
    
        listA.Add(YourCloneMethod(a));
    

【讨论】:

【参考方案2】:

由于您无法在迭代时修改列表,因此您可以在迭代之前制作副本:

foreach(var a in listA.ToList())

  //if(a.somecondition is true)
  // create a clone of 'a' and add it to listA
  var copyOfA = /* make copy of a */.
  listA.Add(copyOfA);

【讨论】:

如果这是一个庞大的列表,那将是非常低效的。如果我的一个开发者在 PR 中提交了这个,我会告诉他们重写它。 这也会复制列表中所有原始对象的克隆对象值 你完全正确@DavidG 我在这里看不到任何关于列表大小的信息。请发布您的解决方案,因为您似乎很熟练:) @VA1267 你的评论是什么意思? @VA1267 否,因为在 C# 中,类是按引用而不是按值处理的。如果您正在处理结构,这当然不是一个好的解决方案。【参考方案3】:

我认为创建新列表和复制对象会更简单。

var newList = oldList.SelectMany(item =>

    if (someCondition) 
    
        var updatedClone = // create clone
        return new[]  item, updatedClone ;
    
    return new[]  item ;      
).ToList();

您可以通过引入扩展方法来删除额外数组的创建

public static IEnumerable<Item> TryAddUpdatedClone(this Item item)

    yield return item;
    if (someCondition)
    
        var updatedClone = // create clone with new values
        yield return updatedClone;
    


// Usage
var newList = oldList.SelectMany(item => item.TryAddUpdatedClone()).ToList();

【讨论】:

以上是关于在迭代期间将对象添加到现有列表的主要内容,如果未能解决你的问题,请参考以下文章

在每次迭代期间将新值附加到列表中后,将列表值添加到字典中

迭代期间无法获得单独的引用

Python中 appendextendinsertadd 区别

迭代列表对象的行,如何访问整行?

将新属性添加到另一个数组中的现有对象数组

C++ 列表插入迭代器