2013-06-11 50 views
4

我有一個字符串列表:鴻溝列表中的元素

{"foo", "str1", "str2", ..., "bar", ..., "baz", ...} 

我需要"foo""bar""baz"之間獲得串子列表。

是否有可能與linq做到這一點?

編輯
我需要不看谷底列表兩次的方法。

+0

我會說是的:)你已經嘗試過一些東西?如果是的話與我們分享。 – wonko79

+0

那麼,我花了兩天的時間搜索並嘗試了不同的方法,但沒有找到任何方法,沒有在列表中查看兩次。 – dikyyn

+0

看到我的答案只迭代一次。看起來不像其他解決方案那麼好,但也有訣竅。 – wonko79

回答

6

你可以做到這一點,以罰款的任何其他兩個元素之間的所有元素:

var strings = new[] { "foo", "str1", "str2", ... "bar", ... "baz" }; 
var between = strings.SkipWhile(s => s != "foo").Skip(1) 
        .TakeWhile(s => s != "bar"); // "str1", "str2", ... 

如果你想獲得「foo」和「巴茲」之間的一切,除了「酒吧」,用這個(假設爲了「富」,「酒吧」,「巴茲」):

var strings = new[] { "foo", "str1", "str2", ... "bar", ... "baz" }; 
var between = strings.SkipWhile(s => s != "foo").Skip(1) 
        .TakeWhile(s => s != "baz") 
        .Where(s => s != "bar"); // "str1", "str2", ... 

或者,如果你願意使用LINQ查詢有副作用,你可以做到這一點通過某些「停止」分割你的輸入列表字數:

var stops = new[] { "foo", "bar", "baz" }; 
var strings = new[] { "foo", "str1", "str2", "bar", "str3", "baz" }; 
var p = -1; 
var partitions = 
    from s in strings 
    let i = Array.IndexOf(stops, s) 
    group s by p = i == -1 ? p : i into g 
    where g.Key == 0 || g.Key == 1 
    select g.Skip(1); // { "str1", "str2" }, { "str3" } 

或略微更有效的(因爲它的第三站單詞後停止處理):

var partitions = 
    (from s in strings 
     let i = Array.IndexOf(stops, s) 
     group s by p = i == -1 ? p : i) 
    .SkipWhile(g => g.Key < 0) 
    .Take(2) 
    .Select(g => g.Skip(1)); // { "str1", "str2" }, { "str3" } 

現在,這種方法是周圍的邊緣有點粗糙,它有點繁瑣,當涉及到「foo」之前或「baz」之後的項目,但如果因爲您只查找「foo」和「baz」之間的項目,它應該適合您。它具有額外的好處,即停用詞的順序不會影響結果。

+0

是的,但我也需要''bar「'和'」baz「'之間的子列表。用你的方法,我需要兩次查看列表。我想知道是否可以在一行中完成。 – dikyyn

+0

@dikyyn如果您知道訂單「foo」,「bar」,「baz」,您可以一次完成並排除「bar」。看到我更新的答案。 –

+0

我知道這似乎是不可能的,但我需要2個獨立的子列表 – dikyyn

4
var idxFoo = list.IndexOf("foo"); 
var idxBar = list.IndexOf("bar"); 
var idxBaz = list.IndexOf("baz"); 

var subList1 = list.Skip(idxFoo).Take(idxBar - idxFoo); 
var subList2 = list.Skip(idxBar).Take(idxBaz - idxBar); 
0

如果你想通過你的大量數據列表只有一次迭代,你可以這樣做:

List<string> longDataList = new List<string> { "foo", "str1", "str2", "str1", "str2", "str1", "str2", "bar", "str1", "str2", "str1", "str2", "str1", "str2", "baz", "str1", "str2", "str1", "str2", "str1", "str2" }; 
List<string> splitters = new List<string> { "foo", "bar", "baz" }; 
Dictionary<string, List<string>> resultDict = new Dictionary<string, List<string>>(); 
List<string> currentList = null; 
longDataList.ForEach(s => 
    { 
     if (splitters.Contains(s)) 
      { 
      if (resultDict.ContainsKey(s)) 
       currentList = resultDict[s]; 
      else 
       { 
       currentList = new List<string>(); 
        resultDict.Add(s, currentList); 
       } 
      } 
     else 
      currentList.Add(s); 
    }); 

透過大量的數據列表使用至少有一點LINQ,但不會把戲迭代只有一次。