在我们代码的许多地方,我们都有对象集合,我们需要从中创建一个以逗号分隔的列表。收集的类型各不相同:它可能是我们需要某个列的DataTable,或者是List< Customer>等。
现在我们遍历集合并使用字符串连接,例如:
string text = "";
string separator = "";
foreach (DataRow row in table.Rows)
{
text += separator + row["title"];
separator = ", ";
}
这有更好的模式吗?理想情况下,我希望通过发送函数来从每个对象中获取正确的字段/属性/列,我们可以重用一种方法。
答案 0 :(得分:95)
string.Join(", ", Array.ConvertAll(somelist.ToArray(), i => i.ToString()))
答案 1 :(得分:11)
static string ToCsv<T>(IEnumerable<T> things, Func<T, string> toStringMethod)
{
StringBuilder sb = new StringBuilder();
foreach (T thing in things)
sb.Append(toStringMethod(thing)).Append(',');
return sb.ToString(0, sb.Length - 1); //remove trailing ,
}
像这样使用:
DataTable dt = ...; //datatable with some data
Console.WriteLine(ToCsv(dt.Rows, row => row["ColName"]));
或:
List<Customer> customers = ...; //assume Customer has a Name property
Console.WriteLine(ToCsv(customers, c => c.Name));
我手边没有编译器,但从理论上说它应该可行。众所周知,理论上,实践和理论都是一样的。在实践中,他们不是。
答案 2 :(得分:10)
// using System.Collections;
// using System.Collections.Generic;
// using System.Linq
public delegate string Indexer<T>(T obj);
public static string concatenate<T>(IEnumerable<T> collection, Indexer<T> indexer, char separator)
{
StringBuilder sb = new StringBuilder();
foreach (T t in collection) sb.Append(indexer(t)).Append(separator);
return sb.Remove(sb.Length - 1, 1).ToString();
}
// version for non-generic collections
public static string concatenate<T>(IEnumerable collection, Indexer<T> indexer, char separator)
{
StringBuilder sb = new StringBuilder();
foreach (object t in collection) sb.Append(indexer((T)t)).Append(separator);
return sb.Remove(sb.Length - 1, 1).ToString();
}
// example 1: simple int list
string getAllInts(IEnumerable<int> listOfInts)
{
return concatenate<int>(listOfInts, Convert.ToString, ',');
}
// example 2: DataTable.Rows
string getTitle(DataRow row) { return row["title"].ToString(); }
string getAllTitles(DataTable table)
{
return concatenate<DataRow>(table.Rows, getTitle, '\n');
}
// example 3: DataTable.Rows without Indexer function
string getAllTitles(DataTable table)
{
return concatenate<DataRow>(table.Rows, r => r["title"].ToString(), '\n');
}
答案 3 :(得分:10)
我找到了string.Join和Lambda Select&gt;有助于编写最少的代码。
List<string> fruits = new List<string>();
fruits.Add("Mango");
fruits.Add("Banana");
fruits.Add("Papaya");
string commaSepFruits = string.Join(",", fruits.Select(f => "'" + f + "'"));
Console.WriteLine(commaSepFruits);
List<int> ids = new List<int>();
ids.Add(1001);
ids.Add(1002);
ids.Add(1003);
string commaSepIds = string.Join(",", ids);
Console.WriteLine(commaSepIds);
List<Customer> customers = new List<Customer>();
customers.Add(new Customer { Id = 10001, Name = "John" });
customers.Add(new Customer { Id = 10002, Name = "Robert" });
customers.Add(new Customer { Id = 10002, Name = "Ryan" });
string commaSepCustIds = string.Join(", ", customers.Select(cust => cust.Id));
string commaSepCustNames = string.Join(", ", customers.Select(cust => "'" + cust.Name + "'"));
Console.WriteLine(commaSepCustIds);
Console.WriteLine(commaSepCustNames);
Console.ReadLine();
答案 4 :(得分:6)
您可以编写一个将IEnumerable转换为逗号分隔字符串
的函数public string Concat(IEnumerable<string> stringList)
{
StringBuilder textBuilder = new StringBuilder();
string separator = String.Empty;
foreach(string item in stringList)
{
textBuilder.Append(separator);
textBuilder.Append(item);
separator = ", ";
}
return textBuilder.ToString();
}
然后,您可以使用Linq查询您的集合/数据集/ etc以提供stringList。
答案 5 :(得分:6)
在.NET 4中,您可以string.Join(", ", table.Rows.Select(r => r["title"]))
答案 6 :(得分:2)
顺便说一下:我要做的第一个修改就是使用StringBuilder Class而不仅仅是一个字符串 - 它会为你节省资源。
答案 7 :(得分:2)
我喜欢Matt Howells answer在这篇文章中:
我不得不把它变成一个扩展名:
public static string ToCsv<T>(this IEnumerable<T> things, Func<T, string> toStringMethod)
用法:[我收到所有电子邮件并将其转换为电子邮件的csv字符串]:
var list = Session.Find("from User u where u.IsActive = true").Cast<User>();
return list.ToCsv(i => i.Email);
答案 8 :(得分:2)
对于集合,您也可以使用此方法,例如:
string.Join(", ", contactsCollection.Select(i => i.FirstName));
您可以选择要分隔的任何属性。
答案 9 :(得分:1)
string strTest = "1,2,4,6";
string[] Nums = strTest.Split(',');
Console.Write(Nums.Aggregate<string>((first, second) => first + "," + second));
//OUTPUT:
//1,2,4,6
答案 10 :(得分:0)
这是我最喜欢的问题, 并更正转换为ConvertAll:
string text = string.Join(", ", Array.ConvertAll(table.Rows.ToArray(), i => i["title"]));