如何使用 linq 查询具有嵌套列表的对象?

How to query object with nested lists using linq?

我将来自第三方提供商的 JSON 反序列化为一个对象,并想查询该对象以查找特定 属性 中的值。

我的问题是对象有一个 属性 (Parts),其值是一个相同类型的列表。

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

当部件 属性 可以有 6 或 7 个级别时,如何查询此对象以找到特定值?

这是我收到的 JSON 答复的示例:

{
  "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": []
                }
              ]
            }
        }
    }
}

试试这个:

        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;
    }

或使用@Parrish对非递归函数的建议:

        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);
        }
    }

用法示例:

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