2012-10-02 16 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; 
} 
相关问题