簡體   English   中英

按元素划分子列表中的列表

[英]Divide list in sublists by elements

我有一個字符串列表:

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

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

用linq可以做到這一點嗎?

編輯
我需要一個方法,而不是兩次查看列表。

您可以這樣做來細化任何兩個其他元素之間的所有元素:

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

如果你想獲得“foo”和“baz”之間的所有內容,除了“bar”,請使用此(假設訂單為“foo”,“bar”,“baz”):

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”之間的項目,它應該適合你。 它具有額外的好處,即停用詞的順序不會影響結果。

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);

如果您只想通過擴展數據列表迭代一次,則可以執行以下操作:

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,但只需通過您的大量數據列表迭代一次。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM