转换扁平结构的最简单有效的方法是什么:
object[][] rawData = new object[][]
{
{ "A1", "B1", "C1" },
{ "A1", "B1", "C2" },
{ "A2", "B2", "C3" },
{ "A2", "B2", "C4" }
// .. more
};
进入分层结构:
class X
{
public X ()
{
Cs = new List<string>();
}
public string A { get; set; }
public string B { get; set; }
public List<string> Cs { get; private set; }
}
结果应如下所示
// pseudo code which describes structure:
result =
{
new X() { A = "A1", B = "B1", Cs = { "C1", "C2" } },
new X() { A = "A2", B = "B2", Cs = { "C3", "C4" } }
}
最好使用Linq扩展方法。目标类X
可以更改(例如,列表的公共设置者),但前提是不可能/有用。
答案 0 :(得分:7)
针对这种特殊情况:
.GroupBy( x => new { a = x[0], b = x[1] } )
.Select( x => new { A = x.Key.a, B = x.Key.b, C = x.Select( c => c[2] ) })
答案 1 :(得分:2)
如果您的层次结构的深度有限,那么这样的事情应该有效(如您的示例中只有三个级别A,B和C)。我简化了你的X
:
class X {
public string A { get; set; }
public string B { get; set; }
public List<string> Cs { get; set; }
}
然后您可以根据需要多次使用嵌套GroupBy
(取决于层次结构的深度)。将它重写为递归方法(这适用于任意深层次结构)也相对容易:
// Group by 'A'
rawData.GroupBy(aels => aels[0]).Select(a =>
// Group by 'B'
a.GroupBy(bels => bels[1]).Select(b =>
// Generate result of type 'X' for the current grouping
new X { A = a.Key, B = b.Key,
// Take the third element
Cs = b.Select(c => c[2]).ToList() }));
这比其他解决方案更明确,但也许它更具可读性,因为它更直接地编码了这个想法......
答案 2 :(得分:1)
如果X成员是字符串而Cs是私有集,而rawData是对象数组的数组,我会向X public X(string a, string b, List<string> cs)
添加构造函数然后执行此代码
var query = from row in rawData
group row by new { A = row[0], B = row[1] } into rowgroup
select new X((string)rowgroup.Key.A, (string)rowgroup.Key.B, rowgroup.Select(r => (string)r[2]).ToList());
这是关于以下原始数据
object[][] rawData = new object[][]
{
new object[] { "A1", "B1", "C1" },
new object[] { "A1", "B1", "C2" },
new object[] { "A2", "B2", "C3" },
new object[] { "A2", "B2", "C4" }
// .. more
};
答案 3 :(得分:0)
我想看看我是否可以在没有匿名实例的情况下编写此代码。这还不错:
IEnumerable<X> myList =
from raw0 in rawData
group raw0 by raw0[0] into g0
let g1s =
(
from raw1 in g0
group raw1 by raw1[1]
)
from g1 in g1s
select new X()
{
A = g0.Key,
B = g1.Key,
C = g1.Select(raw2 => raw2[2]).ToList()
}