int数组转换为string

在C#中,我有一个整数,只包含数字。 我想将这个数组转换为string。

数组示例:

int[] arr = {0,1,2,3,0,1}; 

如何将其转换为格式为"012301"的string?

at.net 3.5使用:

  String.Join("", new List<int>(array).ConvertAll(i => i.ToString()).ToArray()); 

at.net 4.0或以上使用:(请参阅@Jan Remunda的答案)

  string result = string.Join("", array); 

我意识到我的意见可能不是那么受欢迎,但是我想我在Linq-y乐队车上难以驾驭。 这很漂亮 这是浓缩的。 我明白了,我不反对在合适的地方使用它。 也许这只是我自己,但是我觉得人们已经停止了创build实用函数来实现他们想要的东西,而宁愿使用(有时)过多的Linq代码行来代替它们的代码,以便创build一个密集的一行代码。

我并不是说人们在这里提供的任何Linq答案都是不好的,但是我想我觉得这些单行代码可能开始变得越来越长,越来越模糊,因为你需要处理各种情况。 如果你的数组为null呢? 如果你想要一个分隔的string而不是纯粹的连接? 如果数组中的某些整数是两位数,并且要用前导零填充每个值,那么每个元素的string与其余的长度相同?

以所提供的答案之一为例:

  result = arr.Aggregate(string.Empty, (s, i) => s + i.ToString()); 

如果我需要担心数组为空,现在变成这样:

  result = (arr == null) ? null : arr.Aggregate(string.Empty, (s, i) => s + i.ToString()); 

如果我想要一个逗号分隔的string,现在变成这样:

  result = (arr == null) ? null : arr.Skip(1).Aggregate(arr[0].ToString(), (s, i) => s + "," + i.ToString()); 

这还不算太坏,但是我认为这行代码在做的事情一目了然并不明显。

当然,没有什么能够阻止你将这一行代码放到你自己的实用函数中,这样你就不会在应用程序逻辑中混入那么长时间的混乱,特别是当你在多个地方进行时:

  public static string ToStringLinqy<T>(this T[] array, string delimiter) { // edit: let's replace this with a "better" version using a StringBuilder //return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(array[0].ToString(), (s, i) => s + "," + i.ToString()); return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(new StringBuilder(array[0].ToString()), (s, i) => s.Append(delimiter).Append(i), s => s.ToString()); } 

但是,如果你打算把它变成一个效用函数,你真的需要把它凝聚成一个单线吗? 在这种情况下,为什么不为了清晰起见而添加一些额外的行,并利用StringBuilder,以便不重复连接操作:

  public static string ToStringNonLinqy<T>(this T[] array, string delimiter) { if (array != null) { // edit: replaced my previous implementation to use StringBuilder if (array.Length > 0) { StringBuilder builder = new StringBuilder(); builder.Append(array[0]); for (int i = 1; i < array.Length; i++) { builder.Append(delimiter); builder.Append(array[i]); } return builder.ToString() } else { return string.Empty; } } else { return null; } } 

如果你真的关心性能,你甚至可以把它变成一个混合函数,决定是否执行string.Join或使用StringBuilder取决于数组中的元素(这是一个微型优化,不值得在我看来,可能比有益的更有害,但我用它作为这个问题的一个例子):

  public static string ToString<T>(this T[] array, string delimiter) { if (array != null) { // determine if the length of the array is greater than the performance threshold for using a stringbuilder // 10 is just an arbitrary threshold value I've chosen if (array.Length < 10) { // assumption is that for arrays of less than 10 elements // this code would be more efficient than a StringBuilder. // Note: this is a crazy/pointless micro-optimization. Don't do this. string[] values = new string[array.Length]; for (int i = 0; i < values.Length; i++) values[i] = array[i].ToString(); return string.Join(delimiter, values); } else { // for arrays of length 10 or longer, use a StringBuilder StringBuilder sb = new StringBuilder(); sb.Append(array[0]); for (int i = 1; i < array.Length; i++) { sb.Append(delimiter); sb.Append(array[i]); } return sb.ToString(); } } else { return null; } } 

对于这个例子来说,性能的影响可能不值得关注,但重点是,如果你处于一个确实需要关注你的操作性能的情况,无论它是什么,那么它很可能是处理实用程序function比使用复杂的Linqexpression式更容易,更易读。

那个效用函数看起来有点笨重。 现在让我们抛弃混合的东西,做到这一点:

  // convert an enumeration of one type into an enumeration of another type public static IEnumerable<TOut> Convert<TIn, TOut>(this IEnumerable<TIn> input, Func<TIn, TOut> conversion) { foreach (TIn value in input) { yield return conversion(value); } } // concatenate the strings in an enumeration separated by the specified delimiter public static string Delimit<T>(this IEnumerable<T> input, string delimiter) { IEnumerator<T> enumerator = input.GetEnumerator(); if (enumerator.MoveNext()) { StringBuilder builder = new StringBuilder(); // start off with the first element builder.Append(enumerator.Current); // append the remaining elements separated by the delimiter while (enumerator.MoveNext()) { builder.Append(delimiter); builder.Append(enumerator.Current); } return builder.ToString(); } else { return string.Empty; } } // concatenate all elements public static string ToString<T>(this IEnumerable<T> input) { return ToString(input, string.Empty); } // concatenate all elements separated by a delimiter public static string ToString<T>(this IEnumerable<T> input, string delimiter) { return input.Delimit(delimiter); } // concatenate all elements, each one left-padded to a minimum length public static string ToString<T>(this IEnumerable<T> input, int minLength, char paddingChar) { return input.Convert(i => i.ToString().PadLeft(minLength, paddingChar)).Delimit(string.Empty); } 

现在我们有单独的,相当紧凑的效用函数,每个函数都可以自行讨论。

最后,我的观点并不是你不应该使用Linq,而只是说,不要忘记创build你自己的效用函数的好处,即使它们很小,也许只包含一个返回结果的单一行一行Linq代码。 如果没有其他的东西,你就可以保持你的应用程序代码比使用Linq代码更加简洁,如果你在多个地方使用它,那么使用效用函数可以更容易地调整你的输出以防你以后需要改变它。

对于这个问题,我宁愿在我的应用程序代码中写下这样的内容:

  int[] arr = { 0, 1, 2, 3, 0, 1 }; // 012301 result = arr.ToString<int>(); // comma-separated values // 0,1,2,3,0,1 result = arr.ToString(","); // left-padded to 2 digits // 000102030001 result = arr.ToString(2, '0'); 

为了避免创build额外的数组,您可以执行以下操作。

 var builder = new StringBuilder(); Array.ForEach(arr, x => builder.Append(x)); var res = builder.ToString(); 

您可以简单地使用String.Join函数和分隔符使用空string它在内部使用StringBuilder。

 string result = string.Join(string.Emtpy, new []{0,1,2,3,0,1}); 

例如:如果使用分号分号,则结果为:“0; 1; 2; 3; 0; 1”。 它实际上使用空分隔符,第二个参数可以枚举任何对象,如:

 string result = string.Join(null, new object[]{0,1,2,3,0,"A",DateTime.Now}); 
 string result = arr.Aggregate("", (s, i) => s + i.ToString()); 

(免责声明:如果你有很多数字(至less是数百),你关心性能,我build议避开这个方法,并使用StringBuilder ,就像JaredPar的答案一样)。

你可以做:

  int[] arr = {0,1,2,3,0,1}; string results = string.Join("",arr.Select(i => i.ToString()).ToArray()); 

这给你你的结果。

我喜欢用StringBuilderAggregate() 。 “技巧”是Append()返回StringBuilder实例本身:

 var sb = arr.Aggregate( new StringBuilder(), ( s, i ) => s.Append( i ) ); var result = sb.ToString(); 
 string.Join("", (from i in arr select i.ToString()).ToArray()) 

在.NET 4.0中, string.Join可以直接使用IEnumerable<string>

 string.Join("", from i in arr select i.ToString()) 

最有效的方法不是将每个int转换为一个string,而是从一个字符数组中创build一个string。 然后垃圾收集只有一个新的临时对象担心。

 int[] arr = {0,1,2,3,0,1}; string result = new string(Array.ConvertAll<int,char>(arr, x => Convert.ToChar(x + 0x30))); 

我已经在这里留下了后代,但不build议使用它,因为它不是非常可读的。 尤其是现在,我回过头来看看是否过了一段时间,想知道我在写什么的时候想的是什么(我可能认为是垃圾,在别人发布答案之前必须先写下来) 。)

 string s = string.Concat(arr.Cast<object>().ToArray()); 

如果这是很长的arrays,你可以使用

 var sb = arr.Aggregate(new StringBuilder(), ( s, i ) => s.Append( i ), s.ToString());