我有以下 JSON 结构:
{
"Layers": [
{
"Name": "Layer 1",
"Features": [
{
"Name": "Feature 1",
"Properties": {
"Custom property A": "someValue",
"Custom property B": "someValue"
}
},
{
"Name": "Feature 2",
"Properties": {
"Custom property A": "someValue",
"Custom property B": "someValue"
}
}
]
},
{
"Name": "Layer 2",
"Features": [
{
"Name": "Feature 1",
"Properties": {
"Custom property A": "someValue",
"Custom property B": "someValue"
}
},
{
"Name": "Feature 2",
"Properties": {
"Custom property A": "someValue",
"Custom property B": "someValue"
}
}
]
}
]
}
我已经反序列化(使用QuickType)到以下类结构中:
public class Data
{
public List<Layer> Layers { get; set; }
}
public class Layer
{
public string Name { get; set; }
public List<Feature> Features { get; set; }
}
public class Feature
{
public string Name { get; set; }
public JObject Properties { get; set; }
}
注意:您可以看到
Properties
类中的 Feature
属性,它是 JObject
而不是另一个类 - 这是因为那里保存的属性因用户而异。这就是整个问题的由来。
目标是检查某个“自定义属性”的使用位置(在哪些层和哪些功能中)。这个自定义属性的名称是用户输入的(有点像搜索)。
例如(使用上述数据),如果用户输入“自定义属性 A”,我需要向他显示以下响应:
The Custom property A is used in:
Layer 1
Feature 1
Feature 2
Layer 2
Feature 1
Feature 2
我的第一步是获取所有独特的自定义属性,如下所示:
List<string> allProps = _data.Layers.SelectMany(layer => layer.Features)
.SelectMany(feature => feature.Properties.Properties().Select(jProperty => jProperty.Name))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
现在我的第二步是使用 foreach 循环遍历
allProps
并搜索使用自定义属性名称的位置,然后将其存储在如下对象中:
Dictionary<string, Dictionary<string, List<string>>> dictionary;
这样,我可以稍后访问字典(如
dictionary[userInputCustomPropertyName]
),然后计算响应,而不必在用户每次“搜索”时处理整个数据文件,因为它是一个巨大的文件。
问题是我不知道第二步要做什么。我已经尝试了我能想到的 LINQ 方法的任何组合,但我无法让它工作。 我将非常感谢任何帮助。谢谢!
这对我有用
var data = JsonConvert.DeserializeObject<Data>(json);
var customProperty = "Custom property A";
Console.WriteLine($"Custom property {customProperty} is used in:");
Console.WriteLine();
foreach (var layer in data.Layers)
{
var featureNames = layer.Features
.Where(i => i.Properties.Properties()
.Any((j => j.Name == customProperty ))).Select(i => i.Name);
Console.WriteLine(layer.Name);
Console.WriteLine(string.Join("\n", featureNames));
Console.WriteLine();
}