简体   繁体   English

从列表A中删除元素集并使用Linq添加到列表B中

[英]Remove set of elements from list A and add into list B using Linq

I am attempting to lean linq by replacing existing code in a project with linq calls. 我试图通过用linq调用替换项目中的现有代码来倾斜linq。 In this method I check for a condition in my list of lines and if the condition is true, move that element from lines to processedLines. 在这个方法中,我检查行列表中的条件,如果条件为真,则将该元素从行移动到processedLines。

The data structures are just lists: 数据结构只是列表:

List<LineSegment2> lines;
List<LineSegment2> processedLines;

The original code was: 原始代码是:

for (int i = lines.Count - 1; i >= 0; i--)
{           
   if (lines[i].P2.x < sweepPosition)
   {
      processedLines.Add(lines[i]);
      lines.RemoveAt(i);
   }
}

and my linq code is: 我的linq代码是:

var toMove = lines.FindAll(x => x.P2.x < sweepPosition);
toMove.ForEach(x =>
{
   processedLines.Add(x);
   lines.Remove(x);
});

My question is: Is this linq code less efficient because it is using more memory creating the temporary list 'toMove'. 我的问题是:这个linq代码效率低,因为它使用更多内存创建临时列表'toMove'。 Is there a way to create the linq query without requiring the temporary list or is the original code always more efficient? 有没有办法在不需要临时列表的情况下创建linq查询,或者原始代码是否总是更有效?

A more LINQy solution would be to add all the processed lines at once, then get the remaining lines: 一个更LINQy的解决方案是一次添加所有已处理的行,然后获取剩余的行:

processedLines.AddRange(lines.Where(x => x.P2.x < sweepPosition));
lines = lines.Where(x => x.P2.x >= sweepPosition).ToList();

As for efficiency, it won't be quite as fast as your original code. 至于效率,它不会像原始代码那么快。 That's not why you use LINQ. 这不是你使用LINQ的原因。

There is one potential advantage, though. 但是,有一个潜在的优势。 It will make a new list of lines, so if you move a lot of lines to the processed list it will get rid of the unused items in the list. 它将创建一个新的行列表,因此如果您将大量行移动到已处理的列表,它将删除列表中未使用的项。

The "linq" code is less efficient and (more importantly) not necessarily much easier to maintain. “linq”代码效率较低,(更重要的是)不一定更容易维护。 Stick with your original code if you must choose between these two alternatives. 如果您必须在这两种选择中进行选择,请坚持使用原始代码。 I'd just recommend you run the for loop forward -- no reason you should run it backwards like you're doing. 我只是建议你运行for循环 - 没有理由你应该像你正在做的那样向后运行它。

As a side note, I wonder if it would be appropriate for your use case to just maintain a single list and add an IsProcessed property to the LineSegment2 class. 作为旁注,我想知道您的用例是否适合维护单个列表并向LineSegment2类添加IsProcessed属性。 You might consider that. 你可能会考虑这一点。

I'm not really sure about the efficiency...but in Linq I'll do it like this 我不太确定效率......但是在Linq我会这样做

processedLines = processedLines.Concat(lines.Where(x => x < sweepPosition)).ToList();
lines.RemoveAll(x => x < sweepPosition);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM