c# Json用他的级别检索一个特定的节点



我创建了两个c#类,然后对返回的Json进行反序列化以本地使用它。

class structureTree
{
public structureChildren[] children { get; set; }
}
class structureChildren
{
public structureChildren[] children { get; set; }
public string myentity { get; set; }
public bool sonGuide { get; set; }
public string from { get; set; }
public Int64 structureId { get; set; }
public string to { get; set; }
}

返回的数据是这样的

[
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"myentity": "ENT2_A",
"from": "2019-10-01",
"structureId": 34353,
"to": null
},
{
"children": [
{
"children": [],
"myentity": "ENT3_A",
"from": "2019-10-01",
"structureId": 34349,
"to": null
},
{
"children": [],
"myentity": "ENT3_B",
"from": "2019-10-01",
"structureId": 34351,
"to": null
}
],
"myentity": "ENT2_B",
"from": "2019-10-01",
"structureId": 34348,
"to": null
}
],
"myentity": "ENT1_A",
"from": "2019-10-01",
"structureId": 34348,
"to": null
}
],
"myentity": "ENT0_A",
"from": "2019-10-01",
"structureId": 34348,
"to": null
}
]
}   
]   

我需要得到所有的"myentity"元素,以及是否可能驻留在哪个级别。

如果不可能获得级别,另一种方法是获得所有的"myentity">

可能有更好、更优雅的方法来做到这一点。这是没有考虑太多的:

void Main()
{
var st = JsonConvert.DeserializeObject<List<structureTree>>(myjson);
List<Tuple<string,int>> entities = new List<System.Tuple<string, int>>();
foreach (var stc in st)
{
foreach (var sc in stc.children)
{
GetMyEntity(entities, sc, 0);
}
}
foreach (var e in entities)
{
Console.WriteLine($"{e.Item1}, {e.Item2}");
}
}
void GetMyEntity(List<Tuple<string,int>> entities, structureChildren c, int level)
{
entities.Add(Tuple.Create(c.myentity,level));
level++;
foreach (var sc in c.children)
{
GetMyEntity(entities, sc, level);
}
}
class structureTree
{
public structureChildren[] children { get; set; }

}
class structureChildren
{
public structureChildren[] children { get; set; }
public string myentity { get; set; }
public bool sonGuide { get; set; }
public string from { get; set; }
public Int64 structureId { get; set; }
public string to { get; set; }
}
static readonly string myjson = @"[
{
""children"": [
{
""children"": [
{
""children"": [
{
""children"": [],
""myentity"": ""ENT3_A"",
""from"": ""2019-10-01"",
""structureId"": 34353,
""to"": null
},
{
""children"": [
{
""children"": [],
""myentity"": ""ENT3_B"",
""from"": ""2019-10-01"",
""structureId"": 34349,
""to"": null
},
{
""children"": [],
""myentity"": ""ENT3_C"",
""from"": ""2019-10-01"",
""structureId"": 34351,
""to"": null
}
],
""myentity"": ""ENT2_A"",
""from"": ""2019-10-01"",
""structureId"": 34348,
""to"": null
}
],
""myentity"": ""ENT1_1"",
""from"": ""2019-10-01"",
""structureId"": 34348,
""to"": null
}
]
}
]
}
]";

输出:

, 0
ENT1_1, 1
ENT3_A, 2
ENT2_A, 2
ENT3_B, 3
ENT3_C, 3

有两种方法,堆栈/队列或递归。我个人更喜欢堆栈,因为递归很难调试。这是速写稿。我相信其他人可以用Linq给你一个漂亮的递归版本,但我认为这说明了你需要更好地采取的步骤。

using System;
using System.Collections.Generic;
public class Program
{       
public static void Main()
{       
var structure = new StructureTree();
var currentStack = new Stack<StructureChildren>(structure.children);
var nextStack = new Stack<StructureChildren>();
var flatStructure = new List<KeyValuePair<int, string>>();
int currentLevel = 0;
bool loop = true;

while (loop)
{
var currentItem = currentStack.Pop();

foreach (var child in currentItem.children)
nextStack.Push(child);

flatStructure.Add(new KeyValuePair<int, string>(currentLevel, currentItem.myentity));

if (currentStack.Count == 0)
{
if (nextStack.Count == 0)
break;
currentLevel++;
currentStack = new Stack<StructureChildren>(nextStack);
nextStack.Clear();
}
}       
}

public class StructureTree
{
public StructureChildren[] children { get; set; }
}

public class StructureChildren
{
public StructureChildren[] children { get; set; }
public string myentity { get; set; }
public bool sonGuide { get; set; }
public string from { get; set; }
public Int64 structureId { get; set; }
public string to { get; set; }
}
}

PS:请参考Microsoft提供的命名约定。Class名称应该大写ateveryword和属性名称。您当前的命名方案通常用于Java,而不是c#。

相关内容

最新更新