每行C#CSV到JSON

时间:2017-05-02 22:56:02

标签: c# arrays json csv split

主要编辑:我在解释时做得不好:(

我有两个班级:

public class UserDefinitions// a list of 'Items', each'group of items belong to a user. I handle User logic elsewhere, and it works flawlessly.  
    {
        public List<Item> items { get; set; }
    }
public class Item //the User definitions. A user could have 1 or 15 of these. They would all be a single 'line' from the CSV file.
    {

       public string definitionKey { get; set; }
       public string defName { get; set; }
       public string defValue { get; set; }

    }

我想用CSV文件构建。我构建了这个CSV文件,所以每次都使用相同的参数。

我在公司的数据库上运行SQL来生成如下结果:http://i.imgur.com/gS1UJot.png

然后我像这样阅读文件:

class Program
{
    static void Main(string[] args)
    {
        var userData = new UserDefinitions();
        var csvList = new List<Item>();
        string json = "";
        string fPath = @"C:\test\csvTest.csv";
        var lines = File.ReadAllLines(fPath);
        Console.WriteLine(lines);
        List<string> udata = new List<string>(lines);
        foreach (var line in udata)
        {
            string[] userDataComplete = line.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);// this cleans any empty cells from the CSV  

            csvList.Add(new Item { definitionKey = userDataComplete[1], defName = userDataComplete[2], defValue = userDataComplete[3] });
        }

        json = JsonConvert.SerializeObject(csvList); //everything below is for debugging/tracking progress  
        Console.WriteLine(json);
        Console.ReadKey();

        StreamWriter sw = new StreamWriter("C:\\test\\testjson.txt");
        sw.WriteLine(json);
        sw.Close();

     }

  }

这个ALMOST做我想要的。输出json来自第一列&#39; csv数据

[{&#34; definitionKey&#34;:&#34; UUID1&#34;&#34;值defname&#34;:&#34;染发&#34;&#34;利用DefValue&#34 ;: &#34;布朗&#34;},{&#34; definitionKey&#34;:&#34; UUID1&#34;&#34;值defname&#34;:&#34;染发&#34;&#34 ;利用DefValue&#34;:&#34;金发&#34;},{&#34; definitionKey&#34;:&#34; UUID1&#34;&#34;值defname&#34;:&#34;染发&# 34;,&#34;利用DefValue&#34;:&#34;蓝色&#34;}]

使用屏幕截图作为示例时,想要的输出应为

[{&#34; attributeDefinitionKey&#34;:&#34; UUID1&#34;&#34;名称&#34;:&#34;染发&#34;&#34;值&#34 ;: &#34;布朗&#34;},{&#34; definitionKey&#34;:&#34; UUID2&#34;&#34;值defname&#34;:&#34; FreckleAmount&#34;&#34 ;利用DefValue&#34;:&#34; 50&#34;}] [{&#34; attributeDefinitionKey&#34;:&#34; UUID1&#34;&#34;名称&#34;:&#34;染发&#34;&#34;值&#34;:&#34 ;金发&#34;},{&#34; definitionKey&#34;:&#34; UUID2&#34;&#34;值defname&#34;:&#34; FreckleAmount&#34;&#34;利用DefValue&# 34;:&#34;空&#34;}] [{&#34; attributeDefinitionKey&#34;:&#34; UUID1&#34;&#34;名称&#34;:&#34;染发&#34;&#34;值&#34;:&#34 ;蓝色&#34;},{&#34; definitionKey&#34;:&#34; uuid3&#34;&#34;值defname&#34;:&#34;纹身&#34;&#34;利用DefValue&# 34;:&#34; 5&#34;}]

我无法随意挑选某些方面,或将其应用于商品。例如,可能有10个用户或5000个用户,但definitionKey将始终为[1],并添加&#39; 3&#39;将获得每个后续的defintionKey。就像defName将始终位于[2]点并且添加3将获得每个后续defName,如果有的话,这就是每行。

我知道我必须添加一些+3逻辑,但不太确定如何合并它。也许是for循环? foreach循环后嵌套的for循环?我觉得我错过了一些明显的东西!

再次感谢您的帮助

1 个答案:

答案 0 :(得分:1)

这将读取行的csv行并将每行转换为json,同时适应列数的变化。

仅当CSV符合您的规则时才有效:
一个userId和
x“物”的数量,每个“Thing”有3列。

private static void Main(string[] args)
    {
        var file = new StreamReader(@"C:\test\csvTest.csv");
        string line;
        var itemsJson = new List<string>();
        file.ReadLine();
        while ((line = file.ReadLine()) != null)
        {
            var sb = new StringBuilder();
            var fields = line.Split(',');


            sb.Append(GetKeyValueJson("UserId", fields[0]));
            for (var i = 1; i < fields.Length; i += 3)
            {
                var x = (i + 3) / 3;
                sb.Append(GetKeyValueJson($"Thing {i + x} ID", fields[i]));
                sb.Append(GetKeyValueJson($"Thing {i + x} ID", fields[i + 1]));


                sb.Append(i + 3 == fields.Length
                    ? GetKeyValueJson($"Thing {i + x} ID", fields[i + 2], true)
                    : GetKeyValueJson($"Thing {i + x} ID", fields[i + 2]));
            }

            itemsJson.Add(WrapJson(sb.ToString()));
        }

        var json = WrapItems(itemsJson);


        Console.ReadLine();
    }

    private static string GetKeyValueJson(string id, string value, bool lastPair = false)
    {
        var sb = new StringBuilder();
        sb.Append('"');
        sb.Append(id);
        sb.Append('"');
        sb.Append(':');
        sb.Append('"');
        sb.Append(value);
        sb.Append('"');
        if (!lastPair)
            sb.Append(',');

        return sb.ToString();
    }

    private static string WrapJson(string s)
    {
        var sb = new StringBuilder();
        sb.Append('{');
        sb.Append(s);
        sb.Append('}');

        return sb.ToString();
    }

    private static string WrapItems(List<string> jsonList)
    {
        var sb = new StringBuilder();
        sb.Append('"');
        sb.Append("Items");
        sb.Append('"');
        sb.Append(':');
        sb.Append('[');
        sb.Append(jsonList.Aggregate((current, next) => current + "," + next));
        sb.Append(']');

        return WrapJson(sb.ToString());
    }
}

它不漂亮,排序会很困难,但只要它在3的位置就应该适应色谱柱量。