我有一个这种格式的字符串数组(每行是数组中的一个插槽):
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();
谢谢大家的帮助!
答案 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;
}