如何将带有点符号和数组的字符串转换为 json?

How can I convert a string with dot notation and arrays to json?

我正在尝试将点表示法的字符串转换为 JSON。

例如,在 Dictionary<string, object> 中,我有以下键值对:

key: "resource.person[0].name"  
value: "bob"

key: "resource.person[1].name"  
value: "dylan"

我有以下代码可以将键的点表示法转换为 JSON 但它会忽略数组:

var formattedDictionary = new Dictionary<string, object>();
   foreach(var pair in returnFields)
   {
      var key = pair.Key;
      var parts = key.Split('.');
      var currentObj = formattedDictionary;
      for (int i = 0; i < parts.Length-1; i++)
      {
         var property = parts[i];
         if (!currentObj.ContainsKey(property))
            currentObj[property] = new Dictionary<string, object>();
         currentObj = (Dictionary<string, object>)currentObj[property];
      }

      currentObj[parts[^1]] = pair.Value;
    }
 return formattedDictionary;

目前Return秒:

{
   "resource": {
      "person[0]": {
         "name" : "bob"
      },
      "person[1]": {
         "name" : "dylan"
      }
   }
}

我需要一些帮助来修改上面的代码,以便也处理数组给我一个看起来像这样的输出

理想Return:

{
   "resource": {
      "person": [
        {
         "name" : "bob"
        },
        {
         "name" : "dylan"
        }
      ]
   }
}

谢谢!

也许像

var formattedDictionary = new Dictionary<string, object>();
foreach (var pair in returnFields)
{
    var key = pair.Key;
    var parts = key.Split('.');
    var currentObj = formattedDictionary;
    for (int i = 0; i < parts.Length - 1; i++)
    {
        var property = parts[i];


        int index = -1;
        //naive handle arrays
        if (property.Contains('['))
        {
            var bits = property.Split('[', ']');
            property = bits[0];
            index = int.Parse(bits[1]);
        }


        if (!currentObj.ContainsKey(property))
        {
            //is it an array
            if (index > -1)
            {
                //make a list of dictionaries instead of just one
                var list = new List<Dictionary<string, object>>();
                currentObj[property] = list;

                //ensure there are enough list entries for us to access the list by index without it going boom
                while (list.Count <= index)
                    list.Add(new Dictionary<string, object>());

                //"travel" to the current obj being the list item, at index whatever            
                currentObj = (Dictionary<string, object>)list[index];
            }
            else {
                currentObj[property] = new Dictionary<string, object>();
                currentObj = (Dictionary<string, object>)currentObj[property];
            }
        }
                    
    }

    currentObj[parts[^1]] = pair.Value;
}

我还没有测试过,但它基本上将“创建一个新的子字典”扩展为“如果它包含一个索引器,那么它必须是一个列表,所以确保有一个足够大的列表来容纳它,并改为前往该列表索引

请注意,formattedDictionary 中的对象不再总是字符串或字典。它现在有时也可能是 List<Dictionary>

这对我有用(使用递归)

private static Dictionary<string, object> CheckAndCreateKey(string key, object value, Dictionary<string, object> dict) 
    {
        if (!key.Contains(".")) 
        {
            dict[key] = value;
            return dict;
        }

        var firstLevel = key.Split('.')[0];
        var remainingParts = key.Replace(firstLevel + ".", ""); 
        var index = -1;
        if (firstLevel.Contains("[")) 
        {
            var bits = firstLevel.Split('[', ']');
            firstLevel = bits[0]; 
            index = int.Parse(bits[1]);
        }

        if (!dict.ContainsKey(firstLevel)) 
        {
            // new property
            var nestedDict = CheckAndCreateKey(remainingParts, value, new Dictionary<string, object>());
            if (index > -1) 
            {
                // this is an Array
                var list = new List<Dictionary<string, object>>();

                while (list.Count <= index) // add require length, in case when index are in the wrong order (e.g. cars[1].make appears first before cars[0].make)
                    list.Add(new Dictionary<string, object>());

                list[index] = nestedDict;
                dict[firstLevel] = list;
                return dict;
            }

            dict[firstLevel] = nestedDict;
            return dict;
        }

        if (index > -1) 
        {
            var list = (List<Dictionary<string, object>>) dict[firstLevel];
            while (list.Count <= index) // add missing items
                list.Add(new Dictionary<string, object>());

            var nestedDict = CheckAndCreateKey(remainingParts, value, (Dictionary<string, object>) list[index]);
            dict[firstLevel] = list;
            return dict;
        }
        
        var current = (Dictionary<string, object>) dict[firstLevel];
        dict[firstLevel] = CheckAndCreateKey(remainingParts, value, current);
        return dict;
    }

    public static Dictionary<string, object> ParseDotNotation(this Dictionary<string, object> input) 
    {
        var formattedDictionary = new Dictionary<string, object>();
        foreach (var pair in input)
        {
            CheckAndCreateKey(pair.Key, pair.Value, formattedDictionary);
        }
        return formattedDictionary;
    }