Title: Convert delimited strings to and from arrays of values in C#
Fairly regularly I need to convert a delimited string into an array of values. For example, I might want to the string "0.16; 0.15; 0.89; 0.02; 0.89; 0.39; 0.71; 0.32" into an array of floats. It's not too hard, but it would be nice if this was a feature that you could just invoke, perhaps from the string class.
This example shows one way that you can convert delimited strings to and from arrays of values.
Array to String
The following extension method converts an array of values into a delimited string.
public static string Join<T>(this T[] values, string delimiter)
{
if (values.Length == 0) return "";
StringBuilder sb = new StringBuilder();
sb.Append(values[0].ToString());
for (int i = 1; i < values.Length; i++)
{
sb.Append(delimiter + values[i].ToString());
}
return sb.ToString();
}
This method uses a type parameter T so it can apply to an array of any kind of item. For example, it can convert an array of int, float, or Customer objects.
If the values array is empty, the method returns an empty string.
If the array is not empty, then the code creates a StringBuilder. (I often just concatenate strings rather than using a StringBuilder because that's less confusing, but we don't know how long this value array will be, so a StringBuilder may save time.)
The code then copies the first value into the StringBuilder. Notice that the code uses the value's ToString() method to convert it from whatever data type it has to a string. If the array contains objects, be sure to override the class's ToString() method to produce a meaningful value.
The method then loops through the remaining items in the array, adding a delimiter and each item to the StringBuilder.
When it has finished, the method returns the text contained in the StringBuilder.
If ints is an array of integers, then you can use a statement such as string ints_string = ints.Join(";") to convert it into a delimited string.
String to Array
The following extension method converts a delimited string into an array of values.
// Convert the string containing a
// delimited list into a T[].
public static T[] SpiltTs<T>(this string values_text,
string separator, StringSplitOptions split_options,
Converter<string, T> converter)
{
string[] values_array =
values_text.Split(separator, split_options);
return Array.ConvertAll<string, T>
(values_array, converter);
}
This method also takes a type parameter T. It cannot tell from its normal parameters what T will be, so you need to include it explicitly when you call the method. (You'll see that shortly.)
The method uses the string class's Split method to convert the delimited string into an array of strings.
It then calls Array.ConvertAll to convert from an array of string to an array of T. The final parameter to this method is a converter function that Array.ConvertAll can use to convert values from one type to another.
As I said, you need explicitly indicate the type T when you call this method. Even though that type is embedded in the converter function's parameter list, the extension method isn't quite smart enough to use that to figure out what T is.
For example, the following code converts the string values_text into an array of integers.
int[] ints = values_text.SpiltTs<int>(
separator, split_options, int.Parse);
Here the converter function is int.Parse.
The split_options parameter should be either StringSplitOptions.None or StringSplitOptions.RemoveEmptyEntries.
Converting Specific Types
The code above works, but it somewhat ugainly because you need to explicitly include the type parameter. To make converting to specific data types a bit easier, I defined the following extension methods.
public static int[] SplitInts(this string values_text,
string separator, StringSplitOptions split_options)
{
return values_text.SpiltTs<int>(
separator, split_options, int.Parse);
}
public static float[] SplitFloats(this string values_text,
string separator, StringSplitOptions split_options)
{
return values_text.SpiltTs<float>(
separator, split_options, float.Parse);
}
Now you just need to invoke these methods for a string, passing in the delimiter and split options. For example, the following code converts a string holding integers into an array of ints.
int[] new_ints = ints_string.SplitInts(
";", StringSplitOptions.RemoveEmptyEntries);
Strings are a special case. You can use string.Join to join an array of strings, but the Join extension method shown earlier also works with strings so you can use it if you want to be consistent.
You can also use the string class's Split method to split a delimited string into an array of strings. One thing I've always found annoying about that method is that you cannot pass it a string to use as a delimiter. Instead you need to create a array of strings to use as delimiters. To make this a bit more consistent, I added the following version of Split.
public static string[] Split(this string values_text,
string delimiter, StringSplitOptions split_options)
{
string[] separators = { delimiter };
return values_text.Split(separators, split_options);
}
This code simply puts the delimiter string into an array and then calls string.Split.
Feel free to add other methods to convert delimited strings to arrays of other data types, or you can use the SpiltTs method and supply the appropriate type parameter and conversion function.
Download the example to experiment with it and to see additional details.
|