Creating a comma separated list from IList<string> or IEnumerable<string>
从
4 +。
1 2 | IList<string> strings = new List<string>{"1","2","testing"}; string joined = string.Join(",", strings); |
详细&;4.0前网解决方案。
1 2 | IEnumerable<string> strings = ...; string[] array = strings.ToArray(); |
它容易写足以当量法:如果你需要帮手
1 2 3 4 |
然后调用它像这样:
1 2 | IEnumerable<string> strings = ...; string[] array = Helpers.ToArray(strings); |
然后你可以调用
1 2 3 4 | // C# 3 and .NET 3.5 way: string joined = string.Join(",", strings.ToArray()); // C# 2 and .NET 2.0 way: string joined = string.Join(",", new List<string>(strings).ToArray()); |
后者是一个mouthful虽然:)
这是可能的最简单的方式做它,和安静性能。也有其他问题-关于到底是什么样的性能,包括(但不限于)这一个。
作为.NET 4.0中,有更多的overloads
1 | string joined = string.Join(",", strings); |
很简单的:)
FYI,.NET 4.0版,有一些额外的
1 2 | public static string Join(string separator, IEnumerable<string> values) public static string Join<T>(string separator, IEnumerable<T> values) |
在最简单的方式做,这是我能看到的
1 | string commaSeparatedList = input.Aggregate((a, x) => a +"," + x) |
我认为创建以逗号分隔的字符串值列表最干净的方法是:
1 | string.Join<string>(",", stringEnumerable); |
下面是一个完整的例子:
1 2 3 4 5 | IEnumerable<string> stringEnumerable= new List<string>(); stringList.Add("Comma"); stringList.Add("Separated"); string.Join<string>(",", stringEnumerable); |
不需要创建助手函数,它内置于.NET 4.0及更高版本中。
因为我在搜索对象列表的特定属性(而不是它的toString())时到达这里,这里是对接受答案的一个补充:
1 2 | var commaDelimited = string.Join(",", students.Where(i => i.Category == studentCategory) .Select(i => i.FirstName)); |
通过性能比较,获胜者是"循环、附加、后退"。实际上,"Enumerable"和"ManualMoveNext"是相同的优点(考虑stddev)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393 Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4 Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0 Clr : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0 Core : .NET Core 4.6.25009.03, 64bit RyuJIT Method | Job | Runtime | Mean | Error | StdDev | Min | Max | Median | Rank | Gen 0 | Allocated | ---------------------- |----- |-------- |---------:|----------:|----------:|---------:|---------:|---------:|-----:|-------:|----------:| StringJoin | Clr | Clr | 28.24 us | 0.4381 us | 0.3659 us | 27.68 us | 29.10 us | 28.21 us | 8 | 4.9969 | 16.3 kB | SeparatorSubstitution | Clr | Clr | 17.90 us | 0.2900 us | 0.2712 us | 17.55 us | 18.37 us | 17.80 us | 6 | 4.9296 | 16.27 kB | SeparatorStepBack | Clr | Clr | 16.81 us | 0.1289 us | 0.1206 us | 16.64 us | 17.05 us | 16.81 us | 2 | 4.9459 | 16.27 kB | Enumerable | Clr | Clr | 17.27 us | 0.0736 us | 0.0615 us | 17.17 us | 17.36 us | 17.29 us | 4 | 4.9377 | 16.27 kB | StringJoin | Core | Core | 27.51 us | 0.5340 us | 0.4995 us | 26.80 us | 28.25 us | 27.51 us | 7 | 5.0296 | 16.26 kB | SeparatorSubstitution | Core | Core | 17.37 us | 0.1664 us | 0.1557 us | 17.15 us | 17.68 us | 17.39 us | 5 | 4.9622 | 16.22 kB | SeparatorStepBack | Core | Core | 15.65 us | 0.1545 us | 0.1290 us | 15.45 us | 15.82 us | 15.66 us | 1 | 4.9622 | 16.22 kB | Enumerable | Core | Core | 17.00 us | 0.0905 us | 0.0654 us | 16.93 us | 17.12 us | 16.98 us | 3 | 4.9622 | 16.22 kB | |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | public class BenchmarkStringUnion { List<string> testData = new List<string>(); public BenchmarkStringUnion() { for(int i=0;i<1000;i++) { testData.Add(i.ToString()); } } [Benchmark] public string StringJoin() { var text = string.Join<string>(",", testData); return text; } [Benchmark] public string SeparatorSubstitution() { var sb = new StringBuilder(); var separator = String.Empty; foreach (var value in testData) { sb.Append(separator).Append(value); separator =","; } return sb.ToString(); } [Benchmark] public string SeparatorStepBack() { var sb = new StringBuilder(); foreach (var item in testData) sb.Append(item).Append(','); if (sb.Length>=1) sb.Length--; return sb.ToString(); } [Benchmark] public string Enumerable() { var sb = new StringBuilder(); var e = testData.GetEnumerator(); bool moveNext = e.MoveNext(); while (moveNext) { sb.Append(e.Current); moveNext = e.MoveNext(); if (moveNext) sb.Append(","); } return sb.ToString(); } } |
使用了https://github.com/dotnet/benchmarkdotnet
这是一个扩展的方法:
1 2 3 4 | public static string Join(this IEnumerable<string> source, string separator) { return string.Join(separator, source); } |
到达一个小晚,但这本是我的贡献,fwiw。我有一个CSV
1 2 3 | string csv = OrderIds.Aggregate(new StringBuilder(), (sb, v) => sb.Append(v).Append(","), sb => {if (0 < sb.Length) sb.Length--; return sb.ToString();}); |
短和甜蜜,建构新的使用StringBuilder的字符串长度由一shrinks StringBuilder,解除负荷和CSV逗号的字符串返回。
我已经更新这个使用多
这是我的方式做它,做它的方式我已经使用的其他语言:
1 2 3 4 5 6 7 8 9 10 11 | private string ToStringList<T>(IEnumerable<T> list, string delimiter) { var sb = new StringBuilder(); string separator = String.Empty; foreach (T value in list) { sb.Append(separator).Append(value); separator = delimiter; } return sb.ToString(); } |
一位丑陋的东西,但它的工作原理:
1 | string divisionsCSV = String.Join(",", ((List<IDivisionView>)divisions).ConvertAll<string>(d => d.DivisionID.ToString("b")).ToArray()); |
给你一个CSV名单后你给它的转换器(在本案例d.divisionid.tostring D = >("B")。
哈克,但工程的制造方法可以扩展到任何?
当我们应该被包围时的特殊需要,例如:
1 2 3 4 5 6 7 | string[] arr = {"jj","laa","123" }; List<string> myList = arr.ToList(); // 'jj', 'laa', '123' Console.WriteLine(string.Join(",", myList.ConvertAll(m => string.Format("'{0}'", m)).ToArray())); |
我们有一个效用函数是这样的:
1 2 3 4 5 6 | public static string Join<T>( string delimiter, IEnumerable<T> collection, Func<T, string> convert ) { return string.Join( delimiter, collection.Select( convert ).ToArray() ); } |
可以用于很多容易:加入收藏
1 2 3 | int[] ids = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233}; string csv = StringUtility.Join(",", ids, i => i.ToString() ); |
注意,我们在收集参数λ因为IntelliSense就在选秀上收集的类型。
如果你已经有一个枚举的字符串,你需要做的所有大学的拷贝。
1 | string csv = string.Join(",", myStrings.ToArray() ); |
希望这是最简单的方法
1 2 3 4 | string Commaseplist; string[] itemList = {"Test1","Test2","Test3" }; Commaseplist = string.join(",",itemList); Console.WriteLine(Commaseplist); //Outputs Test1,Test2,Test3 |
我刚刚解决了这个问题,然后才在本文中讨论。我的解决方案如下:
1 2 3 4 | private static string GetSeparator<T>(IList<T> list, T item) { return (list.IndexOf(item) == list.Count - 1) ?"" :","; } |
叫作:
1 2 3 4 5 6 7 | List<thing> myThings; string tidyString; foreach (var thing in myThings) { tidyString += string.format("Thing {0} is a {1}", thing.id, thing.name) + GetSeparator(myThings, thing); } |
我也可以这样轻易地表达出来,而且效率也会更高:
1 | string.Join(",", myThings.Select(t => string.format("Thing {0} is a {1}", t.id, t.name)); |
所以,你可以使用什么样的信息后,你有一个转换的一个数组的使用方法:由他人所有的学院
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Configuration; namespace ConsoleApplication { class Program { static void Main(string[] args) { CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection(); string[] itemList = {"Test1","Test2","Test3" }; commaStr.AddRange(itemList); Console.WriteLine(commaStr.ToString()); //Outputs Test1,Test2,Test3 Console.ReadLine(); } } } |
编辑:这里是另一个例子
他们可以很容易转换到阵列使用.NET 3.5中的LINQ的扩展。
1 | var stringArray = stringList.ToArray(); |
我在寻找一个好的C方法来连接字符串的时候讨论了这个问题,就像使用mysql方法
CONCAT_WS(', ',tbl.Lastname,tbl.Firstname)
如果firstname为空,则只返回
string.Join(",", strLastname, strFirstname)
在同一情况下将返回
想要第一个行为,我写了以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string strA, string strB, string strC ="") { return JoinStringsIfNotNullOrEmpty(strSeparator, new[] {strA, strB, strC}); } public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string[] arrayStrings) { if (strSeparator == null) strSeparator =""; if (arrayStrings == null) return""; string strRetVal = arrayStrings.Where(str => !string.IsNullOrEmpty(str)).Aggregate("", (current, str) => current + (str + strSeparator)); int trimEndStartIndex = strRetVal.Length - strSeparator.Length; if (trimEndStartIndex>0) strRetVal = strRetVal.Remove(trimEndStartIndex); return strRetVal; } |
你可以使用一个数组转换的ilist拷贝,然后运行一个string.join指挥数组。
1 2 3 |
我的答案是以上的骨料应样解决方案但不调用栈重因为没有明确的代表电话:
1 2 3 4 5 6 7 8 9 10 11 | public static string ToCommaDelimitedString<T>(this IEnumerable<T> items) { StringBuilder sb = new StringBuilder(); foreach (var item in items) { sb.Append(item.ToString()); sb.Append(','); } if (sb.Length >= 1) sb.Length--; return sb.ToString(); } |
当然,一个可以延伸的分隔独立的签名。我真的不是一个风扇的sb.remove)呼叫(我想是做直动过在while循环和使用IEnumerable MoveNext()确定是否或不写逗号。我的小提琴后,绕过解决方案如果我走在它。
这里是我想要的。
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter, Func<T, string> converter) { StringBuilder sb = new StringBuilder(); var en = source.GetEnumerator(); bool notdone = en.MoveNext(); while (notdone) { sb.Append(converter(en.Current)); notdone = en.MoveNext(); if (notdone) sb.Append(delimiter); } return sb.ToString(); } |
临时数组或列表存储所需的NO和NO
在我的图书馆的一个框架的制造变化,在这一方法的签名,每个组合包括一个
我写了一个扩展的方法做它在一方式,这是有效的:
1 2 3 4 5 6 7 8 | public static string JoinWithDelimiter(this IEnumerable<String> that, string delim) { var sb = new StringBuilder(); foreach (var s in that) { sb.AppendToList(s,delim); } return sb.ToString(); } |
这取决于
1 2 3 4 5 6 7 | public static string AppendToList(this String s, string item, string delim) { if (s.Length == 0) { return item; } return s+delim+item; } |
你可以使用