Dani Pazos
Dani Pazos

Reputation: 126

How to query object with nested lists using linq?

I deserialize a JSON from a third-party provider into an object and want to query that object looking for a value in a specific property.

My problem is that the object has a property (Parts) whose value is a list with the same type.

public class RulePartModel
{
    public string isExistsUnder { get; set; }
    public int State { get; set; }       
    public string Value { get; set; }
    public List<RulePartModel> Parts { get; set; }
}

How can I query this object to find a specific Value when the Parts property can have 6 or 7 levels?

Here is a sample of the JSON I receive as an answer:

{
  "isExistsUnder": null,
  "State": "",
  "Value": "CustomElements",
  "Parts": [
    {
      "isExistsUnder": null,
      "State": 0,      
      "Value": "Rule 73",
      "Parts": [
        {
          "isExistsUnder": null,
          "State": "",
          "Value": "For variable initializations",
          "Parts": [
            {
              "isExistsUnder": null, 
              "State": "",             
              "Value": "cupis",
              "Parts": [
                {
                  "isExistsUnder": null,
                  "State":"",
                  "Value": "randomText1",
                  "Parts": []
                },
                {
                  "isExistsUnder": null,
                  "State":"",
                  "Value": "randomText2",
                  "Parts": []
                },
                {
                  "isExistsUnder": null,
                  "State":"",
                  "Value": "randomText3",
                  "Parts": []
                }
              ]
            }
        }
    }
}

Upvotes: 0

Views: 766

Answers (1)

AliReza Sabouri
AliReza Sabouri

Reputation: 5275

try this:

        static void Main(string[] args)
    {
        var testobj = new RulePartModel();
        var results = FindParts(testobj, q => q.Value == "123");
        // results =>>> all objects with your condition
    }
    static IEnumerable<RulePartModel> FindParts(RulePartModel obj, Func<RulePartModel, bool> predicate)
    {
        if (predicate.Invoke(obj))
            yield return obj;
        foreach (var item in obj.Parts)
            foreach (var res in FindParts(item, predicate))
                yield return res;
    }

or use @Parrish suggestion for non-recursive function:

        static IEnumerable<RulePartModel> FindParts(RulePartModel obj)
    {
        var stack = new Stack<RulePartModel>();
        stack.Push(obj);
        while (stack.Count > 0)
        {
            var current = stack.Pop();
            yield return current;
            foreach (var item in current.Parts)
                stack.Push(item);
        }
    }

usage example :

var results = FindParts(testobj).Where(q => q.Value == "123");

Upvotes: 2

Related Questions