我有两个DataTable。 1包含数据和其他包含行之间的关系信息。代码似乎工作正常,期望一些节点丢失。我知道问题的原因,但不知道如何解决问题。
包含数据的DataTable:
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Name");
dataTable.Columns.Add("America");
dataTable.Columns.Add("Japan");
dataTable.Columns.Add("Singapore");
dataTable.Rows.Add("A", 200, 100, 300);
dataTable.Rows.Add("B", 300, 300, 600);
dataTable.Rows.Add("C", 400, 400, 700);
dataTable.Rows.Add("D", 500, 500, 800);
dataTable.Rows.Add("E", 600, 600, 900);
dataTable.Rows.Add("F", 700, 700, 1000);
dataTable.Rows.Add("G", 800, 800, 600);
dataTable.Rows.Add("H", 900, 100, 400);
dataTable.Rows.Add("I", 100, 200, 300);
dataTable.Rows.Add("J", 200, 300, 200);
dataTable.Rows.Add("K", 300, 500, 500);
dataTable.Rows.Add("L", 200, 300, 200);
dataTable.Rows.Add("M", 300, 500, 500);
映射DataTable
DataTable mappingTable = new DataTable();
mappingTable.Columns.Add("Name", typeof(string));
mappingTable.Columns.Add("id", typeof(int));
mappingTable.Columns.Add("parentID", typeof(int));
mappingTable.Rows.Add("A", 1, 0);
mappingTable.Rows.Add("B", 2, 1);
mappingTable.Rows.Add("C", 3, 1);
mappingTable.Rows.Add("D", 4, 0);
mappingTable.Rows.Add("E", 5, 4);
mappingTable.Rows.Add("F", 6, 0);
mappingTable.Rows.Add("G", 7, 6);
mappingTable.Rows.Add("H", 8, 6);
mappingTable.Rows.Add("I", 9, 1);
mappingTable.Rows.Add("J", 10, 0);
mappingTable.Rows.Add("K", 11, 10);
mappingTable.Rows.Add("L", 12, 0);
mappingTable.Rows.Add("M", 13, 0);
转换代码
var data = dataTable.Rows.Cast<DataRow>()
.Select(r => dataTable.Columns.Cast<DataColumn>().ToDictionary(c => c.ColumnName, c => r[c.ColumnName]))
.ToList();
ILookup<int, int> mapping;
mapping = mappingTable.Rows.Cast<DataRow>()
.Where(r => !r["parentID"].Equals(0))
.ToLookup(r => (int)r["parentID"], r => (int)r["id"]);
var output = new List<Dictionary<string, Object>>();
foreach (var group in mapping)
{
data[@group.Key - 1].Add("children", @group.Select(c => data[c - 1]).ToList());
output.Add(data[@group.Key - 1]);
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(output);
缺少节点(L&amp; M)父ID为0的节点已经创建。
{
"Name": "L",
"America": "200",
"Japan": "300",
"Singapore": "200"
}, {
"Name": "M",
"America": "200",
"Japan": "300",
"Singapore": "200"
}
当前输出:
[{
"Name": "A",
"America": "200",
"Japan": "100",
"Singapore": "300",
"children": [{
"Name": "B",
"America": "300",
"Japan": "300",
"Singapore": "600"
}, {
"Name": "C",
"America": "400",
"Japan": "400",
"Singapore": "700"
}, {
"Name": "I",
"America": "100",
"Japan": "200",
"Singapore": "300"
}
]
}, {
"Name": "D",
"America": "500",
"Japan": "500",
"Singapore": "800",
"children": [{
"Name": "E",
"America": "600",
"Japan": "600",
"Singapore": "900"
}
]
}, {
"Name": "F",
"America": "700",
"Japan": "700",
"Singapore": "1000",
"children": [{
"Name": "G",
"America": "800",
"Japan": "800",
"Singapore": "600"
}, {
"Name": "H",
"America": "900",
"Japan": "100",
"Singapore": "400"
}
]
}
]
预期输出:添加缺少的节点
答案 0 :(得分:1)
这是我对所有父母进行循环并添加他们的孩子的更改,然后将它们添加到输出中:
var data = dataTable.Rows.Cast<DataRow>()
.Select(r => dataTable.Columns.Cast<DataColumn>().ToDictionary(c => c.ColumnName, c => r[c.ColumnName]))
.ToList();
var mapping = mappingTable.Rows.Cast<DataRow>()
.Where(r => !r["parentID"].Equals(0))
.ToLookup(r => (int)r["parentID"], r => (int)r["id"]);
var output = new List<Dictionary<string, Object>>();
foreach (var parent in mappingTable.Rows.Cast<DataRow>().Where(r => r["parentID"].Equals(0))) {
var parentID = (int)parent["id"];
if (mapping.Contains(parentID))
data[parentID-1].Add("children", mapping[parentID].Select(c => data[c-1]).ToList());
output.Add(data[parentID-1]);
}
答案 1 :(得分:0)
我个人更喜欢先创建一个模型,这样可以更容易地创建一个树。
模特:
var mappings = mappingTable.Rows.Cast<DataRow>()
.Select(
r => new DataMapping
{
Name = r.Field<string>("Name"),
Id = r.Field<int>("id"),
ParentId = r.Field<int>("parentID"),
}).ToList();
var data = dataTable.Rows.Cast<DataRow>()
.Select(
r => new DataModel
{
Name = r.Field<string>("Name"),
America = Convert.ToInt32(r.Field<string>("America")),
Japan = Convert.ToInt32(r.Field<string>("Japan")),
Singapore = Convert.ToInt32(r.Field<string>("Singapore")),
Id = mappings.Single(m => m.Name.Equals(r.Field<string>("Name"))).Id
}).ToList();
映射数据:
foreach (var mapping in mappings.Where(m => m.ParentId != 0))
{
var parent = data.Single(d => d.Id == mapping.ParentId);
var child = data.Single(d => d.Id == mapping.Id);
parent.Children.Add(child);
}
创建树:
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
输出:
Test.class.getResource()