Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将C中的Dictionary转换为以键为标题的csv?_C#_Linq_Dictionary - Fatal编程技术网

C# 如何将C中的Dictionary转换为以键为标题的csv?

C# 如何将C中的Dictionary转换为以键为标题的csv?,c#,linq,dictionary,C#,Linq,Dictionary,我有一本字典,像: { key1 : List1 {value1a, value2a}, key2 : List2 {value1b, value2b}, ... } 我如何将其放入csv中,看起来像: key1,key2 value1a,value1b value2a,value2b ... 我已经尝试过首先将其转换为数据表,但我的Linq基础知识遇到了问题 dataTable.Columns.AddRange(dataDictionary .Keys .Sele

我有一本字典,像:

{
   key1 : List1 {value1a, value2a},
   key2 : List2 {value1b, value2b},
   ...
}
我如何将其放入csv中,看起来像:

key1,key2
value1a,value1b
value2a,value2b
...
我已经尝试过首先将其转换为数据表,但我的Linq基础知识遇到了问题

dataTable.Columns.AddRange(dataDictionary
  .Keys
  .Select(x => new DataColumn(x, dataDictionary[x])).ToArray());

首先,你得到下面的错误

dataDictionary[x] List<string> can't be converted to System.Type.
其次,下面是假设每个列表长度相同的代码

using System.IO;
using System.Linq;
using System.Text;
using System;
using System.Collections.Generic;
using System.Data;

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, List<string>> values = new Dictionary<string, List<string>>();

        values.Add("key1", new List<string>() { "value1a", "value2a" });
        values.Add("key2", new List<string>() { "value1b", "value2b" });

        DataTable dataTable = new DataTable();

        dataTable.Columns.AddRange(values.Keys.Select(x => new DataColumn(x)).ToArray());

        var totalColumns = dataTable.Columns.Count;

        for(int i = 0; i < totalColumns; i++)
        {
            DataRow dataRow = dataTable.NewRow();

            int fieldNumber = 0;
            foreach(var item in values)
            {
                dataRow[fieldNumber] = values[item.Key][i];
                fieldNumber++;
            }

            dataTable.Rows.Add(dataRow);
        }

        dataTable.WriteToCsvFile("D://Test.csv");
    }
}

public static class Extension
{
    public static void WriteToCsvFile(this DataTable dataTable, string filePath)
    {
        var content = dataTable.GenerateCsvBytes();

        File.WriteAllBytes(filePath, content);
    }

    public static byte[] GenerateCsvBytes(this DataTable dataTable)
    {
        StringBuilder fileContent = new StringBuilder();

        foreach (var col in dataTable.Columns)
        {
            fileContent.Append(col.ToString() + ",");
        }

        fileContent.Replace(",", Environment.NewLine, fileContent.Length - 1, 1);

        foreach (DataRow dr in dataTable.Rows)
        {
            foreach (var column in dr.ItemArray)
            {
                fileContent.Append("\"" + column.ToString() + "\",");
            }

            fileContent.Replace(",", Environment.NewLine, fileContent.Length - 1, 1);
        }

        return Encoding.ASCII.GetBytes(fileContent.ToString());
    }
}
如果您正在寻找csv,例如csv文件,而不是数据表,您可以直接实现csv行生成器:

代码:

在您将csv写入文件的情况下,您可以将其作为

File.WriteAllLines(@"c:\demo.csv", ToCsv(myDictionary));
如果data.Keys.Count!=data.Values[0]。计数


嘿,纳扬,这真的很棒。我认为这只是添加尽可能多的行和列,但这只适用于这个2x2示例。是否可以修改for循环以根据列表长度填充行?@MarkMcGown如果键的数量与列表长度不同,如何获得CSV?@NetMage列表长度将成为该列表的键作为标题的列的行数。@MarkMcGown抱歉,我不认为这是可以理解的。也许在你的问题上再加几个例子。在CSV文件中,所有列的长度都相同,在CSV文件中,列的数量等于键的数量。如果您选择将字段放入类或结构中,您可能会发现这很有用。然而,它似乎是针对硬编码列的。
public DataColumn(string columnName, Type dataType)
using System.IO;
using System.Linq;
using System.Text;
using System;
using System.Collections.Generic;
using System.Data;

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, List<string>> values = new Dictionary<string, List<string>>();

        values.Add("key1", new List<string>() { "value1a", "value2a" });
        values.Add("key2", new List<string>() { "value1b", "value2b" });

        DataTable dataTable = new DataTable();

        dataTable.Columns.AddRange(values.Keys.Select(x => new DataColumn(x)).ToArray());

        var totalColumns = dataTable.Columns.Count;

        for(int i = 0; i < totalColumns; i++)
        {
            DataRow dataRow = dataTable.NewRow();

            int fieldNumber = 0;
            foreach(var item in values)
            {
                dataRow[fieldNumber] = values[item.Key][i];
                fieldNumber++;
            }

            dataTable.Rows.Add(dataRow);
        }

        dataTable.WriteToCsvFile("D://Test.csv");
    }
}

public static class Extension
{
    public static void WriteToCsvFile(this DataTable dataTable, string filePath)
    {
        var content = dataTable.GenerateCsvBytes();

        File.WriteAllBytes(filePath, content);
    }

    public static byte[] GenerateCsvBytes(this DataTable dataTable)
    {
        StringBuilder fileContent = new StringBuilder();

        foreach (var col in dataTable.Columns)
        {
            fileContent.Append(col.ToString() + ",");
        }

        fileContent.Replace(",", Environment.NewLine, fileContent.Length - 1, 1);

        foreach (DataRow dr in dataTable.Rows)
        {
            foreach (var column in dr.ItemArray)
            {
                fileContent.Append("\"" + column.ToString() + "\",");
            }

            fileContent.Replace(",", Environment.NewLine, fileContent.Length - 1, 1);
        }

        return Encoding.ASCII.GetBytes(fileContent.ToString());
    }
}
key1,key2
value1a,value1b
value2a,value2b
using System.Linq;

...

private static IEnumerable<string> ToCsv(Dictionary<string, List<String>> data) {
  // Quotation if required: 123,45 -> "123,45"; a"bc -> "a""bc" 
  string Quote(string value) => string.IsNullOrEmpty(value) 
      ? "" : value.Contains(',') || value.Contains('"') 
      ? "\"" + value.Replace("\"", "\"\'") + "\""
        : value;

  int rowCount = data.Max(pair => pair.Value.Count);

  // Captions
  yield return string.Join(",", data.Select(pair => Quote(pair.Key)));

  // Rows one after one 
  for (int r = 0; r < rowCount; ++r) 
    yield return string.Join(",", data
      .Select(pair => Quote(r < pair.Value.Count ? pair.Value[r] : "")));
}  
  Dictionary<string, List<string>> data = new Dictionary<string, List<string>>() {
    { "column1", new List<string>() { "C1_A", "C1_B"} },
    { "column2", new List<string>() { "C2_A", "C2_B", "C2_C"} },
    { "column3", new List<string>() { } },
    { "column4", new List<string>() { "C4_A" } },
  };

  // Generate all lines of the csv and combine them with \r\n:
  string csvText = string.Join(Environment.NewLine, ToCsv(data));

  Console.Write(csvText);
column1,column2,column3,column4
C1_A,C2_A,,C4_A
C1_B,C2_B,,
,C2_C,,
File.WriteAllLines(@"c:\demo.csv", ToCsv(myDictionary));
var keys = data.Keys;
Console.WriteLine(String.Join(",", keys));
for (int j1 = 0; j1 < keys.Count; ++j1)
    Console.WriteLine(String.Join(",", data.Values.Select(v => v[j1])));