C# 将通用列表转换为 CSV 字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1890093/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting a generic list to a CSV string
提问by DenaliHardtail
I have a list of integer values (List) and would like to generate a string of comma delimited values. That is all items in the list output to a single comma delimted list.
我有一个整数值列表 (List),并想生成一串逗号分隔的值。即列表中的所有项目输出到单个逗号分隔列表。
My thoughts... 1. pass the list to a method. 2. Use stringbuilder to iterate the list and append commas 3. Test the last character and if it's a comma, delete it.
我的想法... 1. 将列表传递给一个方法。2. 使用 stringbuilder 迭代列表并附加逗号 3. 测试最后一个字符,如果是逗号,则将其删除。
What are your thoughts? Is this the best way?
你怎么看?这是最好的方法吗?
How would my code change if I wanted to handle not only integers (my current plan) but strings, longs, doubles, bools, etc, etc. in the future? I guess make it accept a list of any type.
如果我将来不仅要处理整数(我当前的计划),还要处理字符串、长整数、双精度数、布尔值等,我的代码将如何更改?我想让它接受任何类型的列表。
采纳答案by jason
It's amazing what the Framework already does for us.
框架已经为我们所做的一切令人惊讶。
List<int> myValues;
string csv = String.Join(",", myValues.Select(x => x.ToString()).ToArray());
For the general case:
对于一般情况:
IEnumerable<T> myList;
string csv = String.Join(",", myList.Select(x => x.ToString()).ToArray());
As you can see, it's effectively no different. Beware that you might need to actually wrap x.ToString()
in quotes (i.e., "\"" + x.ToString() + "\""
) in case x.ToString()
contains commas.
如您所见,实际上并没有什么不同。请注意,如果包含逗号,您可能需要实际x.ToString()
用引号括起来(即"\"" + x.ToString() + "\""
)x.ToString()
。
For an interesting read on a slight variant of this: see Comma Quibblingon Eric Lippert's blog.
有关此问题的轻微变体的有趣阅读:请参阅Eric Lippert 博客上的Comma Quibbling。
Note: This was written before .NET 4.0 was officially released. Now we can just say
注意:这是在 .NET 4.0 正式发布之前编写的。现在我们只能说
IEnumerable<T> sequence;
string csv = String.Join(",", sequence);
using the overload String.Join<T>(string, IEnumerable<T>)
. This method will automatically project each element x
to x.ToString()
.
使用重载String.Join<T>(string, IEnumerable<T>)
。此方法将自动将每个元素投影x
到x.ToString()
.
回答by Jo?o Angelo
You can use String.Join
.
您可以使用String.Join
.
String.Join(
",",
Array.ConvertAll(
list.ToArray(),
element => element.ToString()
)
);
回答by Whatsit
You can create an extension method that you can call on any IEnumerable:
您可以创建一个可以在任何 IEnumerable 上调用的扩展方法:
public static string JoinStrings<T>(
this IEnumerable<T> values, string separator)
{
var stringValues = values.Select(item =>
(item == null ? string.Empty : item.ToString()));
return string.Join(separator, stringValues.ToArray());
}
Then you can just call the method on the original list:
然后你可以调用原始列表上的方法:
string commaSeparated = myList.JoinStrings(", ");
回答by Krishna
in 3.5, i was still able to do this. Its much more simpler and doesnt need lambda.
在 3.5 中,我仍然能够做到这一点。它更简单,不需要 lambda。
String.Join(",", myList.ToArray<string>());
回答by Frank M.
Any solution work only if List a list(of string)
任何解决方案仅在列出(字符串)列表时才有效
If you have a generic list of your own Objects like list(of car) where car has n properties, you must loop the PropertiesInfo of each car object.
如果您有自己的对象的通用列表,例如汽车具有 n 个属性的列表(汽车),则必须循环每个汽车对象的 PropertiesInfo。
Look at: http://www.csharptocsharp.com/generate-csv-from-generic-list
看看:http: //www.csharptocsharp.com/generate-csv-from-generic-list
回答by Zain Ali
If any body wants to convert list of custom class objectsinstead of list of stringthen override the ToString method of your class with csv row representation of your class.
如果任何主体想要转换自定义类对象列表而不是字符串列表,则使用类的 csv 行表示覆盖类的 ToString 方法。
Public Class MyClass{
public int Id{get;set;}
public String PropertyA{get;set;}
public override string ToString()
{
return this.Id+ "," + this.PropertyA;
}
}
Then following code can be used to convert this class list to CSV with header column
然后可以使用以下代码将此类列表转换为带有标题列的CSV
string csvHeaderRow = String.Join(",", typeof(MyClass).GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(x => x.Name).ToArray<string>()) + Environment.NewLine;
string csv= csvHeaderRow + String.Join(Environment.NewLine, MyClass.Select(x => x.ToString()).ToArray());
回答by Ali Umair
As the code in the link given by @Frank Create a CSV File from a .NET Generic Listthere was a little issue of ending every line with a ,
I modified the code to get rid of it.Hope it helps someone.
正如@Frank从 .NET 通用列表中创建一个 CSV 文件给出的链接中的代码一样,有一个小问题是用,
我修改了代码以摆脱它来结束每一行。希望它对某人有所帮助。
/// <summary>
/// Creates the CSV from a generic list.
/// </summary>;
/// <typeparam name="T"></typeparam>;
/// <param name="list">The list.</param>;
/// <param name="csvNameWithExt">Name of CSV (w/ path) w/ file ext.</param>;
public static void CreateCSVFromGenericList<T>(List<T> list, string csvCompletePath)
{
if (list == null || list.Count == 0) return;
//get type from 0th member
Type t = list[0].GetType();
string newLine = Environment.NewLine;
if (!Directory.Exists(Path.GetDirectoryName(csvCompletePath))) Directory.CreateDirectory(Path.GetDirectoryName(csvCompletePath));
if (!File.Exists(csvCompletePath)) File.Create(csvCompletePath);
using (var sw = new StreamWriter(csvCompletePath))
{
//make a new instance of the class name we figured out to get its props
object o = Activator.CreateInstance(t);
//gets all properties
PropertyInfo[] props = o.GetType().GetProperties();
//foreach of the properties in class above, write out properties
//this is the header row
sw.Write(string.Join(",", props.Select(d => d.Name).ToArray()) + newLine);
//this acts as datarow
foreach (T item in list)
{
//this acts as datacolumn
var row = string.Join(",", props.Select(d => item.GetType()
.GetProperty(d.Name)
.GetValue(item, null)
.ToString())
.ToArray());
sw.Write(row + newLine);
}
}
}
回答by Griffo
I like a nice simple extension method
我喜欢一个不错的简单扩展方法
public static string ToCsv(this List<string> itemList)
{
return string.Join(",", itemList);
}
Then you can just call the method on the original list:
然后你可以调用原始列表上的方法:
string CsvString = myList.ToCsv();
Cleaner and easier to read than some of the other suggestions.
比其他一些建议更清晰、更易于阅读。
回答by Chong Ching
http://cc.davelozinski.com/c-sharp/the-fastest-way-to-read-and-process-text-files
http://cc.davelozinski.com/c-sharp/the-fastest-way-to-read-and-process-text-files
This website did some extensive testing about how to write to a file using buffered writer, reading line by line seems to be the best way, using string builder was one of the slowest.
该网站对如何使用缓冲写入器写入文件进行了一些广泛的测试,逐行读取似乎是最好的方法,使用字符串生成器是最慢的方法之一。
I use his techniques a great deal for writing stuff to file it works well.
我大量使用他的技术来写东西归档它工作得很好。
回答by vbjay
The problem with String.Join is that you are not handling the case of a comma already existing in the value. When a comma exists then you surround the value in Quotes and replace all existing Quotes with double Quotes.
String.Join 的问题在于您没有处理值中已经存在逗号的情况。当逗号存在时,您可以将引号中的值括起来,并用双引号替换所有现有的引号。
String.Join(",",{"this value has a , in it","This one doesn't", "This one , does"});
See CSV Module
请参阅CSV 模块