2012-06-12 53 views
0

我試圖通過用linq調用替換項目中的現有代碼來依靠linq。在這種方法中,我檢查行列表中的條件,如果條件爲真,則將該元素從行移動到processedLines。從列表A中刪除一組元素並添加到列表B中使用Linq

的數據結構只是列出:

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

原始代碼是:

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

和我的LINQ代碼:

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

我的問題是:這是LINQ代碼效率較低,因爲它使用更多的內存來創建臨時列表'toMove'。有沒有一種方法可以創建linq查詢而不需要臨時列表或原始代碼總是更有效?

+5

您的「LINQ」代碼根本不使用LINQ。 FindAll和ForEach都存在於.NET 2中,不屬於LINQ。 –

+0

您不需要將'toMove'的所有元素添加到'processedLines',您可以讓'processedLines'成爲調用'FindAll'的結果 – weidi

+0

@weidi:假設'processedLines'爲空。 – Guffa

回答

1

更LINQy的解決辦法是在一旦所有的加工線添加,然後得到其餘行:

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

至於效率,它不會像原來的代碼一樣快。這不是你使用LINQ的原因。

雖然有一個潛在的優勢。它會創建一個新的行列表,所以如果將很多行移動到已處理列表中,它將清除列表中未使用的項目。

0

我真的不知道有關的效率......但在LINQ的我會做這樣的

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

它看起來像processedLines.AddRange(lines.Where(x => x.P2.x TaintedLemon

1

「linq」代碼效率較低,並且(更重要的是)不一定更容易維護。如果您必須選擇這兩種選擇,請堅持使用您的原始代碼。我只是建議你向前運行for循環 - 沒有理由讓它像你一樣向後運行。

作爲一個附註,我想知道是否適合您的使用案例,只保留一個列表並將IsProcessed屬性添加到LineSegment2類。你可能會考慮這一點。

+0

謝謝。我絕對更喜歡舊代碼,因爲這是我習慣的,但我只是使用這個項目作爲使用LINQ /代表/ lambda表達式的藉口。很高興知道它效率較低。 – TaintedLemon