2010-11-03 72 views
3

我可以做到這一點沒有循環遍歷整個列表?查找列表中包含x或y的所有行?

List<string> responseLines = new List<string>(); 

然後,該列表將填充大約300行文本。

接下來,我想搜索列表並創建以「abc」開頭或包含「xyz」的所有行的第二個列表。

我知道我可以爲每個做一個,但有沒有更好/更快的方式?

+2

Linq對於這個東西來說真棒:) – 2010-11-03 23:32:40

+1

如果你保持你的列表排序,那麼你可以找到所有以「abc」開頭的行,而不必遍歷所有行,但是你找不到包含「 xyz「而不看每一個。 – Gabe 2010-11-03 23:46:24

回答

7

您可以使用LINQ。這是沒有什麼不同的性能,明智的使用foreach - 這幾乎是它做什麼幕後 - 但你可能喜歡的語法:

var query = responseLines.Where(s => s.StartsWith("abc") || s.Contains("xyz")) 
         .ToList(); 

(如果你很高興與IEnumerable<string>處理,而不是List<string>那麼你可以忽略最後的ToList調用)

+1

請注意,這仍然遍及整個列表,您不必自己編寫'foreach'。 – Gabe 2010-11-03 23:35:04

+0

僅供參考 - 'Contains'應該是「xyz」 – Phil 2010-11-03 23:36:01

+0

這反覆遍歷每行中的每個字符。 – Svisstack 2010-11-03 23:36:25

3

使用LINQ:

List<string> list = responseLines.Where(x => x.StartsWith("abc") || x.Contains("xyz")).ToList(); 
+0

這樣迭代每行中的每個字符。 – Svisstack 2010-11-03 23:37:12

+3

+1抵消Svisstack。 – Inisheer 2010-11-03 23:38:53

4
var newList = (from line in responseLines 
       where line.StartsWith("abc") || line.Contains("xyz") 
       select line).ToList(); 
+0

這對每行中的每個字符進行迭代。 – Svisstack 2010-11-03 23:36:48

+0

對投票表示好奇。 – Inisheer 2010-11-03 23:36:50

+3

@Svisstack:我們聽到了你;你不需要冷靜地回答每個答案並重復自己。此外,你的錯誤表現是:你的答案正確地解決了這個問題,所以根據常見問題沒有顯示降低表決的情況。 – CesarGon 2010-11-03 23:39:20

4

試試這個:

List<string> responseLines = new List<string>(); 
List<string> myLines = responseLines.Where(line => line.StartsWith("abc", StringComparison.InvariantCultureIgnoreCase) || line.Contains("xyz")).ToList(); 

StartsWithContains快捷方式 - 如果StartsWith不滿足要求的Contains只會評估。這仍然遍歷整個列表,但當然,如果您想檢查整個列表,但無法避免這種情況,但它可以幫您節省 輸入foreach

+0

這對每行中的每個字符進行迭代。 – Svisstack 2010-11-03 23:38:01

+4

+1抵消Svisstack。 – Inisheer 2010-11-03 23:39:38

+0

@Svisstack - 當你做一個Contains時,很難避免這樣做,你可以做的最好的事情就是避免Contains,如果由於首先遇到另一個條件而不需要該行。至少我們讓任何內置於LINQ的智能進行角色迭代。我沒有看到你提出了一個避免這個問題的解決方案? – slugster 2010-11-03 23:42:29

1

LINQ可以很好地爲您提供改進的語法(參見LukeH的一個很好的例子),但這並不比手工迭代更快。

如果您需要經常執行此操作,您可能想要提供某種索引數據結構,以便在列表中查看所有「abc」或「xyz」字符串,從而可以使用更快的算法可以在詢問時提供它們,而不是遍歷整個列表。

如果您不必經常這樣做,那很可能是「不成熟的優化」。

2

除非您因爲某些原因需要所有文本,否則在生成List時檢查每一行會更快,並放棄不添加它們時不匹配的行。

這取決於List的加載方式 - 代碼未顯示。如果您從文本文件中讀取數據,這將會很有效,因爲您可以直接使用LINQ查詢直接對輸入數據進行操作,使用File.ReadLines作爲源代替最終的List<string>

var query = File.ReadLines("input.txt"). 
     Where(s => s.StartsWith("abc") || s.Contains("xyz")) 
     .ToList(); 
1

很簡單,沒有可能的算法可以保證你永遠不必遍歷列表中的每個項目。但是,在開始搜索之前,可以改進需要迭代的項目數量 - 對列表進行排序。通過這樣做,唯一需要遍歷整個列表的時間是隻填充「abc」和「xyz」。

假設在您需要搜索時有一個預先排序的列表是不切實際的,那麼提高搜索速度的唯一方法就是使用與列表不同的數據結構 - 例如,一個binary search tree

相關問題