重新排序/添加空列时复制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 ..
答案 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]);
你必须在最后处理额外的','