2012-10-02 13 views
1

我在這個格式的字符串陣列(每一行是在陣列中的狹槽):使用LINQ以提取出一個字符串數組的部分成一個新的集合

IT1
PID

參考
REF
IT1
PID
REF
IT1
PID
參考
REF
...

我想通過最後REF每個IT1提取到使用LINQ的新數組。新的結果將是IEnumerable<IEnumerable<string>>

使用上面的字符串槽數組示例,新的IEnumerable集合應該包含3個IEnumerable<string>

例如:

類1
IT1
PID


REF
端類1

類2
IT1
PID
REF
端類2

類3
IT1
PID

REF
端類3
...

通知所述陣列的一些部分具有1個REF,一些2 REF和一些3 REF。

如何使用LINQ從IT1中將每個節通過最後一個REF提取到IEnumerable<IEnumerable<string>>的新集合中?

Psudo代碼...

var result = arrayData.Select(s => s.StartsWith("IT1") 
.GroupBy(...) 
.Select(result => new {IT1 through last ref goes here}) 
.ToArray(); 

謝謝大家的幫助!

回答

3

你可以這樣使用GroupBy陣列和一些臨時狀態劃分:

var counter = 0; 
var arrays = input.GroupBy(s => counter += s == "IT1" ? 1 : 0) 
        .Select(g => g.ToArray()) 
        .ToArray(); 

這會給你一個數組的數組;每個子陣列將以"IT1"元素開頭,並以任何輸入結束於下一個"IT1"之前。如果你的數據是有效的,那將是一個"REF"。如果數據無效,則需要指定在這種情況下應該發生的情況。

我不太確定你如何期望這些數組被轉換成匿名對象。匿名對象可能有一個未知的類型名稱,但它們仍然是非常強類型的:您不能動態地決定其成員的數量,名稱和類型。

+0

感謝@Jon這是工作。你是對的,我無法獲得類或匿名類型,所以我編輯了我的原始問題,詢問獲取IEnumerable的IEnumerable字符串。當我到達陣列插槽中CCT陣列的插槽時,我確實需要停止分組。我怎樣才能調整你的代碼來停止並且不包含CCT或任何超過CCT的數組? CCT和項目中的項目不需要,可以被視爲無效。謝謝您的幫助! – Frekster

+1

您可以將@Jon代碼從'g => g.ToArray()'更改爲'g => g.TakeWhile(s => s!=「CCT」)ToArray()' – Wasp

+0

@Frekster:Wasp的評論只是很好。 – Jon

0
public static IEnumerable<IEnumerable<string>> Partitian(IEnumerable<string> source) 
{ 
    List<string> buffer = new List<string>(); 
    int? lastRef = null; 

    int position = 0; 
    foreach (string s in source) 
    { 
     if (s == "REF") 
      lastRef = position; 
     else if (s == "IT1" && lastRef.HasValue) 
     { 
      yield return buffer.Take(lastRef.Value + 1); 
      buffer.Clear(); 
      position = 0; 
      lastRef = null; 
     } 
     buffer.Add(s); 

     position++; 
    } 

    if (buffer.Any() && lastRef.HasValue) 
     yield return buffer; 
} 
相關問題