Querying and Filtering Array of JObjects with Linq

前端 未结 1 388
慢半拍i
慢半拍i 2021-01-19 09:53

I suppose this is another entry in my series of questions, but I\'m stuck again. This time, I\'m having trouble working with a JArray of JObjects and determining the Propert

相关标签:
1条回答
  • 2021-01-19 10:21

    This produces the output you require:

    var root = (JContainer)JToken.Parse(json);
    var query = root.Descendants()
        .Where(jt => (jt.Type == JTokenType.Object) || (jt.Type == JTokenType.Array))
        .Select(jo =>
            {
                if (jo is JObject)
                {
                    if (jo.Parent != null && jo.Parent.Type == JTokenType.Array)
                        return null;
                    // No help needed in this section               
                    // populate and return a JObject for the List<JObject> result 
                    // next line appears for compilation purposes only--I actually want a populated JObject to be returned
                    return new JObject();
                }
    
                if (jo is JArray)
                {
                    var items = jo.Children<JObject>().SelectMany(o => o.Properties()).Where(p => p.Value.Type == JTokenType.String);
                    return new JObject(items);
                }
                return null;
            })
        .Where(jo => jo != null)
        .ToList();
    

    Here I use SelectMany() to flatten the nested enumeration of properties of the enumeration of child objects of jo to a single enumeration of all properties of child objects. o => o.Properties() is a lambda expression mapping the JObject o to its collection of properties, and p => p.Value.Type == JTokenType.String is another lambda mapping a property p (generated by the previous SelectMany clause) to a true/false value indicating whether the property has a string value. Both o and p are lambda input parameters that are implicitly typed.

    Also, in the // No help needed in this section section, objects whose parents are arrays are skipped, since they will get collected by the (jo is JArray) clause.

    Note that if different children of the jo array happen to have identical property names, the JObject constructor may throw a duplicated key exception.

    Forked fiddle.

    0 讨论(0)
提交回复
热议问题