使用LINQ将字符串数组中的节提取到新集合中

时间:2012-10-02 14:05:46

标签: c# arrays linq collections

我有一个这种格式的字符串数组(每行是数组中的一个插槽):

IT1
PID
参考
参考
REF
IT1
PID
REF
IT1
PID
参考
REF
......

我想使用LINQ将每个IT1通过最后一个REF提取到一个新数组中。新结果将是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();

谢谢大家的帮助!

2 个答案:

答案 0 :(得分:3)

您可以使用GroupBy和一些临时状态对数组进行分区:

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

这将为您提供一组数组;每个子数组将以"IT1"元素开头,并以下一个"IT1"之前输入的内容结束。如果您的数据有效,则为"REF"。如果数据无效,则需要指定在这种情况下应该发生的情况。

我不太确定您希望如何将这些数组转换为匿名对象。匿名对象可能具有未知的类型名称,但它们仍然是非常强类型的:您无法动态决定其成员的数量,名称和类型。

答案 1 :(得分: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;
}