在C#中,我有一个int数组,仅包含数字。我想将此数组转换为字符串。
数组示例:
int[] arr = {0,1,2,3,0,1};
如何将其转换为格式为:"012301"
的字符串?
答案 0 :(得分:82)
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);
答案 1 :(得分:27)
您只需使用String.Join功能,并使用string.Empty
作为分隔符,因为它在内部使用StringBuilder
。
string result = string.Join(string.Empty, new []{0,1,2,3,0,1});
例如:如果您使用分号作为分隔符,则结果为0;1;2;3;0;1
。
它实际上可以使用null分隔符,第二个参数可以枚举任何对象,例如:
string result = string.Join(null, new object[]{0,1,2,3,0,"A",DateTime.Now});
答案 2 :(得分:24)
我意识到我的观点可能不是很受欢迎,但我想我很难跳上Linq-y乐队的旅行车。这很漂亮。它凝聚了。我明白了,我并不反对在合适的地方使用它。也许这只是我,但我觉得人们已经不再考虑创建实用功能来实现他们想要的东西,而是倾向于使用(有时)过长的Linq代码来为了创建密集的1-liner而丢弃他们的代码。
我不是说人们在这里提供的任何Linq答案都很糟糕,但我想我觉得这些单行代码可能会开始变得更长,更加模糊,因为你需要处理各种情况。如果你的数组为空怎么办?如果你想要一个分隔的字符串而不是纯粹的连接怎么办?如果数组中的某些整数是两位数并且您希望用前导零填充每个值,以便每个元素的字符串与其余元素的长度相同,那该怎么办?
以提供的答案之一为例:
result = arr.Aggregate(string.Empty, (s, i) => s + i.ToString());
如果我需要担心数组为空,现在就变成了这个:
result = (arr == null) ? null : arr.Aggregate(string.Empty, (s, i) => s + i.ToString());
如果我想要一个以逗号分隔的字符串,现在就变成了这个:
result = (arr == null) ? null : arr.Skip(1).Aggregate(arr[0].ToString(), (s, i) => s + "," + i.ToString());
这仍然不是太糟糕,但我认为这一行代码的作用并不明显。
当然,没有什么可以阻止你将这行代码放入你自己的实用程序函数中,这样你就不会在应用程序逻辑中混入那么长的混乱,特别是如果你在多个地方都这样做: / p>
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;
}
}
对于这个例子,性能影响可能不值得关注,但重点是,如果您确实需要关注您的操作性能,无论它们是什么,那么它将与使用复杂的Linq表达式相比,在实用程序函数中处理它更容易,更易读。
那个效用函数看起来仍然很笨重。现在让我们抛弃混合物并做到这一点:
// 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,而只是说不要忘记创建自己的实用程序函数的好处,即使它们很小并且可能只包含一行返回一行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');
答案 3 :(得分:20)
为了避免创建额外的数组,您可以执行以下操作。
var builder = new StringBuilder();
Array.ForEach(arr, x => builder.Append(x));
var res = builder.ToString();
答案 4 :(得分:9)
string result = arr.Aggregate("", (s, i) => s + i.ToString());
(免责声明:如果你有很多数字(至少数百个)并且你关心性能,我建议避开这种方法并使用StringBuilder
,就像JaredPar的回答一样。)
答案 5 :(得分:5)
你可以这样做:
int[] arr = {0,1,2,3,0,1};
string results = string.Join("",arr.Select(i => i.ToString()).ToArray());
这可以为您提供结果。
答案 6 :(得分:5)
我喜欢将StringBuilder
与Aggregate()
一起使用。 “技巧”是Append()
返回StringBuilder
实例本身:
var sb = arr.Aggregate( new StringBuilder(), ( s, i ) => s.Append( i ) );
var result = sb.ToString();
答案 7 :(得分:1)
我把这个留给后人,但不建议使用,因为它不是非常易读。现在我回过头来看看是否经过一段时间并且想知道我在写这篇文章时的想法(我可能在考虑废话,必须在其他人发布回答之前写完这篇文章) 。)
string s = string.Concat(arr.Cast<object>().ToArray());
答案 8 :(得分:1)
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())
答案 9 :(得分:1)
最有效的方法是不将每个int转换为字符串,而是从字符数组中创建一个字符串。然后垃圾收集器只有一个新的临时对象需要担心。
int[] arr = {0,1,2,3,0,1};
string result = new string(Array.ConvertAll<int,char>(arr, x => Convert.ToChar(x + '0')));
答案 10 :(得分:0)
如果这是长阵列,你可以使用
var sb = arr.Aggregate(new StringBuilder(), ( s, i ) => s.Append( i ), s.ToString());