JSON.NET LINQ查询JObjects的JArray上的单个JProperty

时间:2018-01-28 17:34:34

标签: linq json.net

我有一个带有此配置的JArray

[
    {
        "name" : "text",
        "age" : 32
    },
    {
        "name" : "text2",
        "age" : 33
    },
]

我希望使用LINQ查询来选择一个包含JObjects的JArray,其中只包含指定给定键的键值。

例如:

GetCollectionOfPropertiesByKey("name");

这将导致:

[
    {
        "name" : "text"
    },
    {
        "name" : "text2"
    },
]

使用相同的逻辑,

GetCollectionOfPropertiesByKey("age");

会导致:

[
    {
        "age" : 32
    },
    {
        "age" : 33
    },
]

1 个答案:

答案 0 :(得分:0)

您没有指定是否需要按名称对属性进行大小写不变的过滤,因此这里是一个带有可选StringComparison参数的扩展方法:

public static class JsonExtensions
{
    public static JArray GetCollectionOfPropertiesByKey(this JArray array, string key, StringComparison comparison = StringComparison.Ordinal)
    {
        if (array == null)
            return null;
        var query = array
            // Filter out array items that are not objects
            .OfType<JObject>()
            // Select the value JToken with the specified key using the specified StringComparison
            .Select(o => o.GetValue(key, comparison))
            // Filter for null (property was not found)
            .Where(v => v != null)
            // And select a new JObject containing just the JPropery parent of the selected value
            .Select(v => new JObject(v.Parent));
        return new JArray(query);
    }
}

如果需要不区分大小写的匹配,请传递StringComparison.OrdinalIgnoreCase

注意:

  • 查询过滤输入数组中JObject类型的所有项目,然后使用JObject.GetValue(String, StringComparison)按键名称获取相应的值。
  • 然后,如果找到某个值,它会使用所选值的parent构建一个新JObject,该值应为JProperty
  • 如果从不需要不区分大小写,则可以使用JObject.Property(String)按键名称获取JProperty,然后构建包含它的JObject,从而简化查询。 ,像这样:

    var query = array
        // Filter out array items that are not objects
        .OfType<JObject>()
        // Select the JProperty with the specified key
        .Select(o => o.Property(key))
        // Filter for null (property was not found)
        .Where(p => p != null)
        // And select a new JObject with just this property
        .Select(p => new JObject(p));
    

示例工作.Net fiddle