You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于JObject属性检索多层数组并构建查询字典

自定义属性图层与要素映射解决方案

输入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"
                    }
                }
            ]
        }
    ]
}

反序列化后的.NET类结构

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; } // 自定义属性为JObject,支持动态键值
}

需求目标

根据用户输入的自定义属性名,检索该属性所在的图层(Layer)及对应要素(Feature),示例输出如下:

The Custom property A is used in:
Layer 1
    Feature 1
    Feature 2
Layer 2
    Feature 1
    Feature 2

已完成步骤:获取所有唯一自定义属性

通过LINQ提取所有不重复的自定义属性名:

List<string> allProps = _data.Layers.SelectMany(layer => layer.Features)
    .SelectMany(feature => feature.Properties.Properties().Select(jProperty => jProperty.Name))
    .Distinct(StringComparer.OrdinalIgnoreCase)
    .ToList();

解决方案:构建属性映射字典

我们需要将每个自定义属性映射到其所在的图层及对应的要素列表,生成Dictionary<string, Dictionary<string, List<string>>>类型的字典(顶层键为属性名,中层键为图层名,值为要素名列表)。以下提供两种实现方式:

方式一:LINQ实现

利用嵌套GroupBy直接构建映射字典,代码简洁:

var propertyMap = _data.Layers
    .SelectMany(layer => layer.Features
        .SelectMany(feature => feature.Properties.Properties()
            .Select(prop => new 
            {
                PropName = prop.Name,
                LayerName = layer.Name,
                FeatureName = feature.Name
            })))
    // 按属性名分组(忽略大小写)
    .GroupBy(x => x.PropName, StringComparer.OrdinalIgnoreCase)
    .ToDictionary(
        g => g.Key,
        g => g.GroupBy(x => x.LayerName)
            .ToDictionary(
                lg => lg.Key,
                lg => lg.Select(x => x.FeatureName).Distinct().ToList()
            ),
        StringComparer.OrdinalIgnoreCase
    );

方式二:循环遍历实现

适合大文件场景,内存占用更可控,逻辑直观:

// 顶层字典:属性名 -> 图层名 -> 要素列表(忽略大小写比较)
var propertyMap = new Dictionary<string, Dictionary<string, List<string>>>(StringComparer.OrdinalIgnoreCase);

foreach (var layer in _data.Layers)
{
    foreach (var feature in layer.Features)
    {
        foreach (var prop in feature.Properties.Properties())
        {
            string propName = prop.Name;
            
            // 初始化属性对应的图层字典
            if (!propertyMap.ContainsKey(propName))
            {
                propertyMap[propName] = new Dictionary<string, List<string>>();
            }
            
            var layerDict = propertyMap[propName];
            
            // 初始化图层对应的要素列表
            if (!layerDict.ContainsKey(layer.Name))
            {
                layerDict[layer.Name] = new List<string>();
            }
            
            var featureList = layerDict[layer.Name];
            
            // 避免重复添加同一要素
            if (!featureList.Contains(feature.Name))
            {
                featureList.Add(feature.Name);
            }
        }
    }
}

使用映射字典查询属性

构建完成后,即可快速查询任意属性的分布:

string targetProperty = "Custom property A";

if (propertyMap.TryGetValue(targetProperty, out var layerFeatureMap))
{
    Console.WriteLine($"The {targetProperty} is used in:");
    foreach (var layerEntry in layerFeatureMap)
    {
        Console.WriteLine(layerEntry.Key);
        foreach (var featureName in layerEntry.Value)
        {
            Console.WriteLine($"    {featureName}");
        }
    }
}
else
{
    Console.WriteLine($"The {targetProperty} was not found in any features.");
}

内容的提问来源于stack exchange,提问作者3AgL3 DeeJay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:40:34