I have a array of integers: int [] number = new int[] { 2,3,6,7 };
What is the easiest way of converting these in to a single string where the number are separated by a character (like: "2,3,4,7"
)?
I'm in C# and .NET 3.5.
I have a array of integers: int [] number = new int[] { 2,3,6,7 };
What is the easiest way of converting these in to a single string where the number are separated by a character (like: "2,3,4,7"
)?
I'm in C# and .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"
EDIT:
I see several solutions advertise usage of StringBuilder. Someone complaints that Join method should take an IEnumerable argument.
I'm going to disappoint you :) String.Join requires array for a single reason - performance. Join method needs to know the size of the data to effectively preallocate necessary amount of memory.
Here is a part of internal implementation of String.Join method:
// 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]);
}
}
I'm too lazy to compare performance of suggested methods. But something tells me that Join will win :)
String.Join(";", number.Select(item => item.ToString()).ToArray());
We have to convert each of the items to a String
before we can join them, so it makes sense to use Select
and a lambda expression. This is equivalent to map
in some other languages. Then we have to convert the resulting collection of string back to an array, because String.Join
only accepts a string array.
The ToArray()
is slightly ugly I think. String.Join
should really accept IEnumerable<String>
, there is no reason to restrict it to only arrays. This is probably just because Join
is from before generics, when arrays were the only kind of typed collection available.
If your array of integers may be large, you'll get better performance using a StringBuilder. E.g.:
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();
Edit: When I posted this I was under the mistaken impression that "StringBuilder.Append(int value)" internally managed to append the string representation of the integer value without creating a string object. This is wrong: inspecting the method with Reflector shows that it simply appends value.ToString().
Therefore the only potential performance difference is that this technique avoids one array creation, and frees the strings for garbage collection slightly sooner. In practice this won't make any measurable difference, so I've upvoted this better solution.
One mixture of the two approaches would be to write an extension method on IEnumerable<T> which used a StringBuilder. Here's an example, with different overloads depending on whether you want to specify the transformation or just rely on plain ToString. I've named the method "JoinStrings" instead of "Join" to avoid confusion with the other type of Join. Perhaps someone can come up with a better name :)
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"), ","));
}
}
I agree with the lambda expression for readability and maintainability, but it will not always be the best option. The downside to using both the IEnumerable/ToArray and StringBuilder approaches is that they have to dynamically grow a list, either of items or characters, since they do not know how much space will be needed for the final string.
If the rare case where speed is more important than conciseness, the following is more efficient.
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);
You can do
ints.ToString(",")
ints.ToString("|")
ints.ToString(":")
Check out
Separator Delimited ToString for Array, List, Dictionary, Generic IEnumerable
Although the OP specified .NET 3.5, people wanting to do this in .NET 2.0 with C#2 can do this:
string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));
I find there are a number of other cases where the use of the Convert.xxx functions is a neater alternative to a lambda, although in C#3 the lambda might help the type-inferencing.
A fairly compact C#3 version which works with .NET 2.0 is this:
string.Join(",", Array.ConvertAll(ints, item => item.ToString()))
ints.Aggregate("", ( str, n ) => str +","+ n );
I also thought there was a simpler way. Don't know about performance, anyone has any (theoretical) idea?