gpt4 book ai didi

c# - 将扁平化的分层数据转换为树结构的 JSON

转载 作者:行者123 更新时间:2023-11-30 14:58:00 26 4
gpt4 key购买 nike

我有一个 C# 字典对象,其中包含文件名和该文件所在的文件夹。我想将数据转换为分层树。下面是数据。如何将其转换为树结构的 JSON。

我调查了这个example但我无法获得所需的输出。

+-----------------------------------------------+|
| Name | Path
|------------------------------------------------|
| Kitchen supplies | Shopping / Housewares |
| Groceries | Shopping / Housewares |
| Cleaning supplies | Shopping / Housewares |
| Office supplies | Shopping / Housewares |
| Retile kitchen | Shopping / Remodeling |
| Ceiling | Shopping / Paint bedroom |
| Walls | Shopping / Paint bedroom |
| Misc | null |
| Other | Shopping |
+-----------------------------------------------+|

应该生成如下输出:

   {"text":".","children": [
{
Name:' Shopping',
children:[{
Name:'Housewares',
children:[{
Name:'Kitchen supplies',
leaf:true,
},{
Name:'Groceries',
leaf:true,
},{
Name:'Cleaning supplies',
leaf:true,
},{
Name: 'Office supplies',
leaf: true,
}]
}, {
Name:'Remodeling',
children:[{
Name:'Retile kitchen',
leaf:true,
},{
Name:'Paint bedroom',
children: [{
Name: 'Ceiling',
leaf: true
}, {
Name: 'Walls',
iconCls: 'Name',
}]
},
{
Name: 'Other',
leaf: true
}]
}]
},
{
Name: 'Misc',
leaf: true
}
]}

最佳答案

如您链接的示例所示,有两个主要任务。首先,我们需要将字典中的数据转化为分层形式。一旦完成,我们就可以担心将其序列化为 JSON。

首先,我们需要一个 Node 类来表示层次结构:

class Node
{
public Node()
{
Children = new List<Node>();
}

public string Name { get; set; }
public List<Node> Children { get; set; }
}

一旦我们有了它,我们就可以遍历字典并构建树。 (注意:在您想要的 JSON 中,您显示 Paint bedroomOther 从属于 Remodeling,而在您的示例字典数据中它们从属于Shopping。我假设 JSON 在这种情况下是正确的,所以我相应地更改了字典数据,如下所示。)

Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("Kitchen supplies", "Shopping / Housewares");
dict.Add("Groceries", "Shopping / Housewares");
dict.Add("Cleaning supplies", "Shopping / Housewares");
dict.Add("Office supplies", "Shopping / Housewares");
dict.Add("Retile kitchen", "Shopping / Remodeling");
dict.Add("Ceiling", "Shopping / Remodeling / Paint bedroom");
dict.Add("Walls", "Shopping / Remodeling / Paint bedroom");
dict.Add("Misc", null);
dict.Add("Other", "Shopping / Remodeling");

Node root = new Node();
foreach (KeyValuePair<string, string> kvp in dict)
{
Node parent = root;
if (!string.IsNullOrEmpty(kvp.Value))
{
Node child = null;
foreach (string part in kvp.Value.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries))
{
string name = part.Trim();
child = parent.Children.Find(n => n.Name == name);
if (child == null)
{
child = new Node { Name = name };
parent.Children.Add(child);
}
parent = child;
}
}
parent.Children.Add(new Node { Name = kvp.Key });
}

现在我们有了树,我们可以序列化它了。但是,我们需要一些特殊处理,因为您的叶节点与 JSON 中的非叶节点呈现方式不同:叶节点具有 leaf 属性而没有 children 属性,而reverse 对于非叶节点是正确的。为了处理这个逻辑,我们需要一个自定义的 JsonConverter。 (澄清一下,我在这里使用 Json.Net——您的问题没有提到特定的 JSON 序列化程序。)

class NodeConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Node));
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Node node = (Node)value;
JObject jo = new JObject();
jo.Add("name", node.Name);
if (node.Children.Count == 0)
{
jo.Add("leaf", true);
}
else
{
jo.Add("children", JArray.FromObject(node.Children, serializer));
}
jo.WriteTo(writer);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

我们可以像这样使用 JsonConverter 将树序列化为 JSON:

JsonSerializerSettings settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new NodeConverter() },
Formatting = Formatting.Indented
};

string json = JsonConvert.SerializeObject(root, settings);

Console.WriteLine(json);

这是输出:

{
"name": ".",
"children": [
{
"name": "Shopping",
"children": [
{
"name": "Housewares",
"children": [
{
"name": "Kitchen supplies",
"leaf": true
},
{
"name": "Groceries",
"leaf": true
},
{
"name": "Cleaning supplies",
"leaf": true
},
{
"name": "Office supplies",
"leaf": true
}
]
},
{
"name": "Remodeling",
"children": [
{
"name": "Retile kitchen",
"leaf": true
},
{
"name": "Paint bedroom",
"children": [
{
"name": "Ceiling",
"leaf": true
},
{
"name": "Walls",
"leaf": true
}
]
},
{
"name": "Other",
"leaf": true
}
]
}
]
},
{
"name": "Misc",
"leaf": true
}
]
}

另一个小注意事项:在上面你想要的 JSON 中,你用 text 属性而不是 name 属性显示根节点,这与所有其他不一致节点。我假设这是一个错误。如果不是,则需要更改 JsonConverter,以便它具有输出 text 属性的逻辑,如果名称是点( .).

希望这对您有所帮助。

关于c# - 将扁平化的分层数据转换为树结构的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19929696/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com