c# - 将点标记的命名空间字符串列表排序为嵌套的 JSON 字符串 c#

标签 c# json

如何将点标记的命名空间字符串列表排序为嵌套的 JSON 字符串?

像这样。

var string1 = "example.string.1";
var string2 = "example.string.2";
var string3 = "example.anotherstring.1";

分类成这个。

{
    "example": {
        "string": ["1", "2"],
        "anotherstring": ["1"]
    }
}

编辑 1

谢谢大家!我能够使用您的答案让它接近工作。

使用这个列表它可以工作:

var strings = new List<string>
{
    "example.string.1",
    "example.string.2",
    "example.anotherstring.1",
};

public void Example()
{
    var dict = new Dictionary<string, dynamic>();
    foreach (var s in strings)
    {
        AddPartsToDictionary(dict, s.Split('.'));
    }
}

public void AddPartsToDictionary(IDictionary<string, dynamic> dict, string[] parts)
{
    for (var i = 0; i < parts.Length; i++)
    {
        if (i < parts.Length - 2)
        {
            if (!dict.ContainsKey(parts[i]))
                dict.Add(parts[i], new Dictionary<string, dynamic>());
            dict = dict[parts[i]];
        }
        else if (i < parts.Length - 1)
        {
            if (!dict.ContainsKey(parts[i]))
            {
                var list = new List<string>();
                dict[parts[i]] = list;
            }
        }
        else
        {
            var list = dict[parts[i - 1]] as List<string>;
            list.Add(parts[i]);
        }
    }
}

结果json

{
    "example":  {
        "string":  [
            "1",
            "2"    
    ],
        "anotherstring":  [
            "1"    
    ]  
  }
}

这个列表失败了

var strings = new List<string>
{
    "example.string.1",
    "example.string.example.1",
    "example.string.2",
    "example.anotherstring.1",
    "example.string.example.2",
    "string.example.2"
};

我可能需要对列表进行排序或进行其他操作,仍在处理中。希望这有助于解决问题。

最佳答案

对象一直向下

如果一直使用对象(而不是数组)是可以的,那么这会起作用。

var strings = new List<string> {
    "example.string.1",
    "example.string.2",
    "example.anotherstring.1",
};

var result = strings.Aggregate(new Dictionary<string, Object>(), (acc, s) =>
{
    var level = acc;
    foreach(var segment in s.Split('.'))
    {
        if (!level.ContainsKey(segment))
        {
            var child = new Dictionary<string, Object>();
            level.Add(segment, child);
        }

        level = level[segment] as Dictionary<string, Object>;
    }

    return acc;
});

var json = JsonConvert.SerializeObject(result, Formatting.Indented);

输出一直向下都有对象。

{
  "example": {
    "string": {
      "1": {},
      "2": {}
    },
    "anotherstring": {
      "1": {}
    }
  }
}

最后一级的数组 ( with a Fiddle )

如果您想要最后一级的数组,那么我们需要精确定义最后一级的定义。例如,最后一层是否总是只包含整数?如果是这样,以下工作。

var result = strings.Aggregate(new Dictionary<string, Object>(), (acc, s) =>
{
    Dictionary<string, Object> previousLevel = null;
    Dictionary<string, Object> nextLevel = acc;
    string previousSegment = null;
    foreach (string nextSegment in s.Split('.'))
    {
        if (Int16.TryParse(nextSegment, out _))
        {
            if (previousLevel[previousSegment] is Dictionary<string, Object>)
            {
                previousLevel[previousSegment] = new List<string>();
            }

            var list = previousLevel[previousSegment] as List<string>;
            list.Add(nextSegment);
        }
        else
        {
            if (!nextLevel.ContainsKey(nextSegment))
            {
                var child = new Dictionary<string, Object>();
                nextLevel.Add(nextSegment, child);
            }

            previousSegment = nextSegment;
            previousLevel = nextLevel;

            nextLevel = nextLevel[nextSegment] as Dictionary<string, Object>;
        }
    }

    return acc;
});

输出在最后一层有数组。

{
  "example": {
    "string": [
      "1",
      "2"
    ],
    "anotherstring": [
      "1",
      "2"
    ]
  }
}

此数组版本仅在最后一级仅为 integer 类型时才有效,这正是您最初的问题所要求的。

更困难的情况是在同一级别处理混合的 stringinteger 类型,它的输入看起来像这样:

"System.1", 
"System.2", 
"System.Collections.1", 
"System.Collections.2", 
"System.Collections.Generic.1"

这需要更复杂的算法。如果这是隐藏的要求,请考虑提出一个全新的后续问题,并在对此答案的评论中链接到它。

关于c# - 将点标记的命名空间字符串列表排序为嵌套的 JSON 字符串 c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49662193/

相关文章:

java - REST Web 服务 - JSON 请求映射到 java Complex 对象

json - 如何使用 JSON 路径提取器中提取的变量进行场景的进一步步骤?

c# - Visual Studio 2012 C# - 导入 DLL

c# - 基于分组的WCF服务响应设计c#

c# - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) 返回 String.Empty

javascript - 如何将 .json 文件作为参数导入 .js 文件并使用命令行启动它?

javascript - 如何使用 jquery 在运行时创建 json 对象数组?

c# - 实现内部类内部接口(interface)报错

c# - EF核心3 : CLR property 'Number' cannot be added to entity type 'CHSIMTBase' because it is declared on the CLR type 'Contract'

javascript - 从 .json URL 获取数据并使用 Javascript/JQuery 将其显示在 HTML 中