使用嵌套数组反序列化JSON以从值

时间:2015-12-25 14:00:10

标签: c# json regex

在我的申请表中,我有List<Users>

[{
"Id": "1",
"Name": "last, first",
"Skills": [{"SN":"20","SL":"12"},{"SN":"197","SL":"09"}]
},
{
"Id": "2",
"Name": "Black, Jack",
"Skills": [{"SN":"40","SL":"07"},{"SN":"199","SL":"05"}]
},
{
"Id": "3",
"Name": "Rooney, Wayne",
"Skills": [{"SN":"40","SL":"11"},{"SN":"201","SL":"07"}]
}]

我需要将这些数据转换为一个字符串,格式如下:

  

&#34; 1 / last,first / 20-12,197-09; 2 / Black,Jack / 40-07,199-05; 3 / Rooney,   韦恩/ 40-11,201-07&#34;

我尝试序列化此对象以获取JSON字符串:

public IHttpActionResult ImportUsers([FromBody]IEnumerable<Users> newUsers)
{
    string agents = JsonConvert.SerializeObject(newUsers);
    return Ok(agents);
}

得到一个结果:

  

&#34; [{\&#34;标识\&#34;:\&#34; 1 \&#34; \&#34;名称\&#34;:\&#34;持续,   第一\&#34; \&#34;技能\&#34;:[{\&#34; SN \&#34;:\&#34; 20 \&#34; \&#34; SL \&#34;:\&#34; 12 \&#34;},{\&#34; SN \&#34;:\&#34; 197 \&#34; \&#34; SL \&#34;:\&#34; 09 \&#34;}]},{\&#34;标识\&#34;:\&#34; 2 \&#34; \&# 34;名称\&#34;:\&#34;黑色,   杰克\&#34; \&#34;技能\&#34;:[{\&#34; SN \&#34;:\&#34; 40 \&#34; \&#34; SL \&#34;:\&#34; 07 \&#34;},{\&#34; SN \&#34;:\&#34; 199 \&#34; \&#34; SL \&#34;:\&#34; 05 \&#34;}]},{\&#34;标识\&#34;:\&#34; 3 \&#34; \&# 34;名称\&#34;:\&#34;鲁尼,   韦恩\&#34; \&#34;技能\&#34;:[{\&#34; SN \&#34;:\&#34; 40 \&#34; \&#34; SL \&#34;:\&#34; 11 \&#34;},{\&#34; SN \&#34;:\&#34; 201 \&#34; \&#34; SL \&#34;:\&#34; 07 \&#34;}]}]&#34;

我尝试反序列化此字符串以获取每个变量的值

var dict = JsonConvert.DeserializeObject<dynamic>(agents);
            List<string> results = new List<string>();
            foreach (var d in dict)
            {                
                var skills = d["Skills"];                
                string skill = string.Join(",", skills);
                string list = d["Id"] + "/" + d["Name"] + "/" + skill;
                results.Add(list);
            }
            string result = string.Join(";", results);

并获取此字符串:

  

&#34; 1 / last,first / {\ r \ n \&#34; SN \&#34;:\&#34; 20 \&#34;,\ r \ n \&#34 ; SL \&#34;:\&#34; 12 \&#34; \ r \ n},{\ r \ n   \&#34; SN \&#34;:\&#34; 197 \&#34;,\ r \ n \&#34; SL \&#34;:\&#34; 09 \&#34 ; \ r \ n}; 2 /黑色,杰克/ {\ r \ n \&#34; SN \&#34;:   \&#34; 40 \&#34;,\ r \ n \&#34; SL \&#34;:\&#34; 07 \&#34; \ r \ n},{\ r \ n \&#34; SN \&#34;:\&#34; 199 \&#34;,\ r \ n \&#34; SL \&#34;:   \&#34; 05 \&#34; \ r \ n}; 3 /鲁尼,韦恩/ {\ r \ n \&#34; SN \&#34;:\&#34; 40 \&#34 ;,\ r \ n \&#34; SL \&#34;:   \&#34; 11 \&#34; \ r \ n},{\ r \ n \&#34; SN \&#34;:\&#34; 201 \&#34;,\ r \ n \&#34; SL \&#34;:\&#34; 07 \&#34; \ r \ n}&#34;

所以它更像我需要的东西,但我的技能列表中的值仍然存在问题。如何从Id和Name列中获取值?也许我需要再次反序列化这个部分或使用一些正则表达式来实现我需要的字符串?

2 个答案:

答案 0 :(得分:1)

您的预期结果不是有效的json。那么更好的方法是通过c#格式化结果字符串而不使用第三方库。

Laconic方式是使用字符串功能:

public IHttpActionResult ImportUsers([FromBody] IEnumerable<User> newUsers)
{
    var sb = new StringBuilder();

    foreach (var user in newUsers)
    {
        sb.Append(user.Id);
        sb.Append("/");

        sb.Append(user.Name);
        sb.Append("/");

        for (int i = 0; i < user.Skills.Length; i++)
        {
            sb.Append(user.Skills[i].SN);
            sb.Append("-");
            sb.Append(user.Skills[i].SL);
            if (i != user.Skills.Length)
                sb.Append(",");
        }

        sb.Append(";");
    }

    var result = sb.ToString();
    return Ok(result);
}

高效且不易理解(我认为)的方式是使用StringBuilder

import csv
from collections import Counter
from itertools import imap
from operator import  itemgetter

with open('yourcsv') as f:
    next(f) # skip the header
    cn = Counter(imap(itemgetter(2), csv.reader(f)))

    for t in cn.iteritems():
        print("{} appears {} times".format(*t))

答案 1 :(得分:0)

您可以稍微修改代码以使其正常工作。为了以您想要的方式获得技能,您可以嵌套另一个foreach循环,该循环将以所请求的格式创建技能列表:

var dict = JsonConvert.DeserializeObject<dynamic>(agents);
List<string> results = new List<string>();
foreach (var d in dict)
{
    List<string> skills = new List<string>();

    foreach (var s in d["Skills"])
    {
        skills.Add(s["SN"].ToString() + "-" + s["SL"].ToString());
    }

    string skill = string.Join(",", skills);
    string list = d["Id"] + "/" + d["Name"] + "/" + skill;
    results.Add(list);
}
string result = string.Join(";", results);