c# - 如何遍历字典以获取键名并将其传递给字符串

标签 c# json algorithm dictionary data-structures

我想遍历存储嵌套 JSON 的 C# 字典,以检索字典键名并将其传递给字符串,格式为“key1:key1-1:key1-1-1”。

之后,创建一个新的字典,使用特殊排列的字符串作为它的键。

最后,desiredDictionary["key:key:key"] = originalDictionary["key"]["key"]["key"]。

请具体回答,抱歉我是 C# IEnumerable 类和 JSON 的新手。

我已将 JSON 数据存储到字典中,下面给出了示例 JSON。

using System.Web.Script.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

......
string jsonText = File.ReadAllText(myJsonPath);
var jss = new JavaScriptSerializer();

//this is the dictionary storing JSON
var dictJSON = jss.Deserialize<Dictionary<string, dynamic>>(jsonText); 

//this is the dictionary with keys of specially arranged string 
var desiredDict = new Dictionary<string, string>();
......
......
//Here is a sample JSON
{
    "One": "Hey",

    "Two": {
        "Two": "HeyHey"
           }

     "Three": {
        "Three": {
            "Three": "HeyHeyHey"    
                 }
              } 
}

我需要有关字典键名检索、字符串完成和新字典值传递过程的帮助。 根据给定的JSON,desiredDict["Three:Three:Three"] = dictJSON["Three"]["Three"]["Three"] = "HeyHeyHey", 该解决方案有望应用于任何类似的 JSON。

最佳答案

您可以使用递归方法获取 JObject 并从中生成扁平化字典,如下所示:

private static IDictionary<string, string> FlattenJObjectToDictionary(JObject obj)
{
    // obtain a key/value enumerable and convert it to a dictionary
    return NestedJObjectToFlatEnumerable(obj, null).ToDictionary(kv => kv.Key, kv => kv.Value);
}

private static IEnumerable<KeyValuePair<string, string>> NestedJObjectToFlatEnumerable(JObject data, string path = null)
{
    // path will be null or a value like Three:Three: (where Three:Three is the parent chain)

    // go through each property in the json object
    foreach (var kv in data.Properties())
    {
        // if the value is another jobject, we'll recursively call this method
        if (kv.Value is JObject)
        {
            var childDict = (JObject)kv.Value;

            // build the child path based on the root path and the property name
            string childPath = path != null ? string.Format("{0}{1}:", path, kv.Name) : string.Format("{0}:", kv.Name);

            // get each result from our recursive call and return it to the caller
            foreach (var resultVal in NestedJObjectToFlatEnumerable(childDict, childPath))
            {
                yield return resultVal;
            }
        }
        else if (kv.Value is JArray)
        {
            throw new NotImplementedException("Encountered unexpected JArray");
        }
        else
        {
            // this kind of assumes that all values will be convertible to string, so you might need to add handling for other value types
            yield return new KeyValuePair<string, string>(string.Format("{0}{1}", path, kv.Name), Convert.ToString(kv.Value));
        }
    }
}

用法:

var json = "{\"One\":\"Hey\",\"Two\":{\"Two\":\"HeyHey\" },\"Three\":{\"Three\":{\"Three\":\"HeyHeyHey\"}}}";
var jObj = JsonConvert.DeserializeObject<JObject>(json);
var flattened = FlattenJObjectToDictionary(jObj);

它利用了 yield return 将递归调用的结果作为单个 IEnumerable<KeyValuePair<string, string>> 返回然后将其作为平面字典返回。

注意事项:

  • JSON 中的数组将抛出异常(参见 else if (kv.Value is JArray))
  • else处理实际值的部分假定所有值都可以使用 Convert.ToString(kv.Value) 转换为字符串.如果不是这种情况,您将不得不为额外的场景编写代码。

Try it online

关于c# - 如何遍历字典以获取键名并将其传递给字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56861993/

相关文章:

algorithm - 射线(平面)三角形交点

c# - 有一个同步处理程序和一个异步处理程序

C# 定时器或 Thread.Sleep

c# - 在 Loop C# 中创建对象

c# - .NET Standard 中的 GetMethod 等效项

javascript - 忽略空白值对 json 进行排序

json - Perl XML2JSON : How to preserve XML element order?

algorithm - 优化 - 最大化加权贡献的最小值

json - 如何在Jackson的json序列化过程中向对象添加额外的字段?

Python preference finder——如何实现二进制插入排序