在C#中不需要递归就能从嵌套的JSON中找到一个属性的值。

我想从一个嵌套的JSON数据中找到一个属性的值。我有一个使用以下方法的递归方法,而且效果很好。有没有一种方法可以让我把它转换成一个迭代方法。代码片段如下—————————。

    public static class JsonExtensions
    {
        /// <summary>
        /// Finds the value of a JToken from the given JSON data for the given property name.
        /// If the resultant JToken have multiple occurrence at different levels of JSON data the this methods returns the first or default.
        /// </summary>
        /// <param name="containerToken">Given JSON data.</param>
        /// <param name="propertyName">Property name whose value needs to be find.</param>
        /// <returns></returns>
        public static string FindJToken(this JToken containerToken, string propertyName)
        {
            if (containerToken == null)
            {
                throw new ArgumentNullException(nameof(containerToken));
            }

            if (string.IsNullOrWhiteSpace(propertyName))
            {
                throw new ArgumentException("Parameter Cannot be Null, Empty or White spaces.", nameof(propertyName));
            }

            List<JToken> matches = new List<JToken>();
            GetJTokenValue(containerToken, propertyName, matches);
            return matches.FirstOrDefault()?.ToString();
        }

        /// <summary>
        /// Recursive method to find value of the given JToken / property name from the given JSON
        /// </summary>
        /// <param name="containerToken">Given JSON data</param>
        /// <param name="propertyName">Property name whose value needs to be find.</param>
        /// <param name="matches">List of matching tokens</param>
        private static void GetJTokenValue(JToken containerToken, string propertyName, List<JToken> matches)
        {
            if (containerToken.Type == JTokenType.Object)
            {
                foreach (JProperty child in containerToken.Children<JProperty>())
                {
                    if (child.Name == propertyName)
                    {
                        matches.Add(child.Value);
                    }
                    GetJTokenValue(child.Value, propertyName, matches);
                }
            }
            else if (containerToken.Type == JTokenType.Array)
            {
                foreach (JToken child in containerToken.Children())
                {
                    GetJTokenValue(child, propertyName, matches);
                }
            }
        }
}

我想将GetJTokenValue()方法转换为迭代器,并将匹配结果改为IEnumerable,这样就可以避免递归,降低复杂性。任何帮助都将被感激。

谢谢,并致以问候。

Amit Anand

解决方案:

你试过使用JsonPath吗?我发现它对这类情况非常有用。

你并没有给出一个源例,所以我只是做了一些简单的例子。

//{
//  "ToBeFound": "test",
//  "lala": [
//    {
//     "ToBeFound": "test"
//    },
//    {
//     "NotToBeFound": "test2"
//    }
//  ]
//}

var source = JToken.Parse(@"{ ""ToBeFound"": ""test"", ""lala"": [ { ""ToBeFound"": ""test"" }, { ""NotToBeFound"": ""test2"" } ] }");

var results = source.SelectTokens("$..ToBeFound");

foreach(JToken result in results)
    Console.WriteLine(result.Value<string>());

看看它的运行情况: https:/dotnetfiddle.netzoH7FQ.

希望对你有所帮助!

给TA打赏
共{{data.count}}人
人已打赏
未分类

WPF数据化到一个日期时间对象列表

2022-9-9 1:17:21

未分类

如何让map函数返回一个比第一个数组大的数组?

2022-9-9 1:28:31

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索