重新排序/添加空列时复制CSV文件

时间:2015-08-21 17:43:59

标签: c# list csv

重新排序/添加空列时复制CSV文件。

例如,如果输入文件的行中有10列中的3列的值与输出不同(除了第一列是带有列名称的标题):

col2,col6,col4 // first line - column names
2, 5, 8    // subsequent lines - values for 3 columns

和预期产出

col0,col1,col2,col3,col4,col5,col6,col7,col8,col9

然后输出对于col0,col1,col3,col5,col7,col8,col9以及输入文件中col2,col4,col4的值应为“”。因此,对于显示的第二行(2,5,8),预期输出为“,, 2,,5 ,,,,,,”

下面的代码我试过,它比我想要的慢。

我有两个清单。 第一个列表filecolumnnames是通过拆分分隔的字符串(行)创建的,并且会为文件中的每一行重新创建此列表。 第二个列表list具有第一个列表需要重新排列并重新连接的顺序。

这有效

string fileName = "F:\\temp.csv";
//file data has first row col3,col2,col1,col0; 
//second row: 4,3,2,1
//so on

string fileName_recreated = "F:\\temp_1.csv";

int count = 0;
const Int32 BufferSize = 1028;
using (var fileStream = File.OpenRead(fileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize))
{
    String line;
    List<int> list = new List<int>();
    string orderedcolumns = "\"\"";
    string tableheader = "col0,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10";
    List<string> tablecolumnnames = new List<string>();
    List<string> filecolumnnames = new List<string>();
    while ((line = streamReader.ReadLine()) != null)
    {
        count = count + 1;
        StringBuilder sb = new StringBuilder("");
        tablecolumnnames = tableheader.Split(',').ToList();
        if (count == 1)
        {
            string fileheader = line;
            //fileheader=""col2,col1,col0"
            filecolumnnames = fileheader.Split(',').ToList();

            foreach (string col in tablecolumnnames)
            {
                int index = filecolumnnames.IndexOf(col);

                if (index == -1)
                {
                    sb.Append(",");
                   // orderedcolumns=orderedcolumns+"+\",\"";
                   list.Add(-1);
                }
                else
                {
                    sb.Append(filecolumnnames[index] + ",");
                    //orderedcolumns = orderedcolumns+ "+filecolumnnames["+index+"]" + "+\",\"";

                       list.Add(index);
                }

                // MessageBox.Show(orderedcolumns);
            }
        }
        else
        {

            filecolumnnames = line.Split(',').ToList();

            foreach (int items in list)
            {

                //MessageBox.Show(items.ToString());

                if (items == -1)
                {
                    sb.Append(",");
                }
                else
                {
                    sb.Append(filecolumnnames[items] + ",");

                }


            }
           //expected format sb.Append(filecolumnnames[3] + "," + filecolumnnames[2] + "," + filecolumnnames[2] + ",");
            //sb.Append(orderedcolumns);

            var result = String.Join (", ", list.Select(index => filecolumnnames[index]));
        }



            using (FileStream fs = new FileStream(fileName_recreated, FileMode.Append, FileAccess.Write))
            using (StreamWriter sw = new StreamWriter(fs))
            {
                sw.WriteLine(sb.ToString());
            }


    }

我试图通过构造一个字符串orderedcolumns来加快速度,并为每一个循环删除第二个循环,并将其替换为构造的字符串。 所以,如果你取消注释orderedcolumns字符串构造orderedcolumns = orderedcolumns+ "+filecolumnnames["+index+"]" + "+\",\"";并取消注释append sb.Append(orderedcolumns);我期望构造字符串中的值,但是当我追加orderedcolumns时它附加了文本,即 ""+","+filecolumnnames[3]+","+filecolumnnames[2]+","+filecolumnnames[1]+","+filecolumnnames[0]+","+","+","+","+","+","+","

即。我想要它取值filecolumnnames [3]列表中的值,而不是filecolumnnames [3]名称本身。

预期价值:如果该行有1,2,3,4 我希望输出为4,3,2,1,因为filecolumnnames [3]将有4,filecolumnnames [2]将有3 ..

2 个答案:

答案 0 :(得分:1)

String.Join是从序列构造逗号/空格分隔字符串的方法。

var result = String.Join (", ", list.Select(index => filecolumnnames[index]);

由于您只阅读列的子集并且输入和输出中的订单不匹配,因此我使用字典来保存每一行输入。

 var row = tablecolumnnames
       .Zip(line.Split(','), (Name,Value)=> new {Name,Value})
       .ToDictionary(x => x.Name, x.Value);

对于输出I&#39; d从默认值或输入行填充序列:

 var outputLine = String.Join(",",
      filecolumnnames
         .Select(name => row.ContainsKey(name) ? row[name] : ""));

注意代码是输入的而不是编译的。

答案 1 :(得分:0)

orderedcolumns = orderedcolumns+ "+filecolumnnames["+index+"]" + "+\",\""; "   

应该是

orderedcolumns = orderedcolumns+ filecolumnnames[index] + ",";   
但是,你应该像其他人指出的那样使用加入。或者

orderedcolumns.AppendFormat("{0},", filecolumnnames[index]); 

你必须在最后处理额外的','