如何将int 连接到.NET中的字符分隔string?
我有一个整数数组:
int[] number = new int[] { 2,3,6,7 };
什么是最简单的方法转换成一个单一的string数字由字符分隔(如: "2,3,6,7"
)?
我在C#和.NET 3.5中。
var ints = new int[] {1, 2, 3, 4, 5}; var result = string.Join(",", ints.Select(x => x.ToString()).ToArray()); Console.WriteLine(result); // prints "1,2,3,4,5"
编辑 :
我看到几个解决scheme广告使用StringBuilder。 有人抱怨说Join方法应该带一个IEnumerable参数。
我会让你失望:) String.Join需要数组,因为一个原因 – 性能。 Join方法需要知道数据的大小以有效地预先分配必要的内存量。
以下是String.Join方法的内部实现的一部分:
// length computed from length of items in input array and length of separator string str = FastAllocateString(length); fixed (char* chRef = &str.m_firstChar) // note than we use direct memory access here { UnSafeCharBuffer buffer = new UnSafeCharBuffer(chRef, length); buffer.AppendString(value[startIndex]); for (int j = startIndex + 1; j <= num2; j++) { buffer.AppendString(separator); buffer.AppendString(value[j]); } }
我懒得比较build议方法的性能。 但有些事情告诉我,join将赢得:)
尽pipeOP指定了.NET 3.5,但是人们希望在.NET 2.0中用C#2来做到这一点:
string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));
我发现还有一些其他情况,其中使用Convert.xxx函数是lambda的替代品,尽pipe在C#3中lambda可能有助于types推断。
与.NET 2.0一起使用的相当紧凑的C#3版本是这样的:
string.Join(",", Array.ConvertAll(ints, item => item.ToString()))
两种方法的一个混合将是在IEnumerable <T>上使用StringBuilder编写扩展方法。 下面是一个例子,不同的重载取决于你是否要指定转换,或者只是简单的ToString。 我已经命名方法“JoinStrings”而不是“Join”,以避免与其他types的Join混淆。 也许有人可以拿出更好的名字:)
using System; using System.Collections.Generic; using System.Text; public static class Extensions { public static string JoinStrings<T>(this IEnumerable<T> source, Func<T, string> projection, string separator) { StringBuilder builder = new StringBuilder(); bool first = true; foreach (T element in source) { if (first) { first = false; } else { builder.Append(separator); } builder.Append(projection(element)); } return builder.ToString(); } public static string JoinStrings<T>(this IEnumerable<T> source, string separator) { return JoinStrings(source, t => t.ToString(), separator); } } class Test { public static void Main() { int[] x = {1, 2, 3, 4, 5, 10, 11}; Console.WriteLine(x.JoinStrings(";")); Console.WriteLine(x.JoinStrings(i => i.ToString("X"), ",")); } }
String.Join(";", number.Select(item => item.ToString()).ToArray());
我们必须将每个项目转换为一个String
然后才能join它们,所以使用Select
和一个lambdaexpression式是有意义的。 这相当于其他语言的map
。 然后,我们必须将所得到的string集合转换回数组,因为String.Join
只接受一个string数组。
ToArray()
稍微难看,我想。 String.Join
应该真的接受IEnumerable<String>
,没有理由把它限制在只有数组的地方。 这可能只是因为Join
是来自generics之前,当时数组是唯一可用的types集合。
如果你的整型数组很大,你可以使用StringBuilder获得更好的性能。 例如:
StringBuilder builder = new StringBuilder(); char separator = ','; foreach(int value in integerArray) { if (builder.Length > 0) builder.Append(separator); builder.Append(value); } string result = builder.ToString();
编辑:当我发布这个时,我误以为“StringBuilder.Append(int value)”内部设法追加整数值的string表示,而不创build一个string对象。 这是错误的:用Reflector检查方法显示它只是附加value.ToString()。
因此唯一潜在的性能差异是这种技术避免了一个数组的创build,并且稍微更快地释放了垃圾回收的string。 在实践中,这不会有任何可衡量的差异,所以我提出了更好的解决scheme 。
问题是“将这些数字转换成单个string的最简单的方法”。
最简单的方法是:
int[] numbers = new int[] { 2,3,6,7 }; string number_string = string.Join(",", numbers); // do whatever you want with your exciting new number string
编辑:这只适用于.NET 4.0 +,我第一次读到这个问题时,错过了.NET 3.5的要求。
我同意lambdaexpression式的可读性和可维护性,但它并不总是最好的select。 使用IEnumerable / ToArray和StringBuilder方法的缺点是,它们不得不dynamic地增加一个列表,无论是项目还是字符,因为他们不知道最终string需要多less空间。
如果速度比简洁更重要的罕见情况下,效率更高。
int[] number = new int[] { 1, 2, 3, 4, 5 }; string[] strings = new string[number.Length]; for (int i = 0; i < number.Length; i++) strings[i] = number[i].ToString(); string result = string.Join(",", strings);
ints.Aggregate("", ( str, n ) => str +","+ n ).Substring(1);
我也认为有一个更简单的方法。 不了解performance,任何人都有任何(理论上的)想法?
你可以做
ints.ToString(",") ints.ToString("|") ints.ToString(":")
查看
数组,列表,分隔符分隔ToString,通用IEnumerable
在.NET 4.0中,string连接对params object[]
有一个重载,所以它很简单:
int[] ids = new int[] { 1, 2, 3 }; string.Join(",", ids);
例
int[] ids = new int[] { 1, 2, 3 }; System.Data.Common.DbCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM some_table WHERE id_column IN (@bla)"); cmd.CommandText = cmd.CommandText.Replace("@bla", string.Join(",", ids));
在.NET 2.0中,这是一个小小的多一点困难,因为没有这样的过载。 所以你需要你自己的通用方法:
public static string JoinArray<T>(string separator, T[] inputTypeArray) { string strRetValue = null; System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>(); for (int i = 0; i < inputTypeArray.Length; ++i) { string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture); if (!string.IsNullOrEmpty(str)) { // SQL-Escape // if (typeof(T) == typeof(string)) // str = str.Replace("'", "''"); ls.Add(str); } // End if (!string.IsNullOrEmpty(str)) } // Next i strRetValue= string.Join(separator, ls.ToArray()); ls.Clear(); ls = null; return strRetValue; }
在.NET 3.5中,可以使用扩展方法:
public static class ArrayEx { public static string JoinArray<T>(this T[] inputTypeArray, string separator) { string strRetValue = null; System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>(); for (int i = 0; i < inputTypeArray.Length; ++i) { string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture); if (!string.IsNullOrEmpty(str)) { // SQL-Escape // if (typeof(T) == typeof(string)) // str = str.Replace("'", "''"); ls.Add(str); } // End if (!string.IsNullOrEmpty(str)) } // Next i strRetValue= string.Join(separator, ls.ToArray()); ls.Clear(); ls = null; return strRetValue; } }
所以你可以使用JoinArray扩展方法。
int[] ids = new int[] { 1, 2, 3 }; string strIdList = ids.JoinArray(",");
如果您将ExtensionAttribute添加到您的代码中,也可以在.NET 2.0中使用该扩展方法:
// you need this once (only), and it must be in this namespace namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] public sealed class ExtensionAttribute : Attribute {} }