Edward Tanguay
Edward Tanguay

Reputation: 193322

What is the best way to String.Join a non-string array?

What is a shorthand way to String.Join a non-string array as in the second example?

string[] names = { "Joe", "Roger", "John" };
Console.WriteLine("the names are {0}", String.Join(", ", names)); //ok

decimal[] prices = { 39.99M, 29.99m, 29.99m, 19.99m, 49.99m };
Console.WriteLine("the prices are {0}", String.Join(", ", prices)); //bad overload

Upvotes: 5

Views: 1730

Answers (5)

Binary Worrier
Binary Worrier

Reputation: 51711

I have two Delimit functions that do this for me.
They've a very light footprint, in that no second array is created, and where a string is returned, a StringBuilder is used under the covers, so it's not copying and concatenating to the same string causing ever longer concatenation delays.
As such they are useful for series of very large and/or unknown length.

The frist writes to a TextWriter and returns nothing, the second returns a string, and delegates to the first passing in a StringWriter.

public static void Delimit<T>(this IEnumerable<T> me, System.IO.TextWriter writer, string delimiter)
{
    var iter = me.GetEnumerator();
    if (iter.MoveNext())
        writer.Write(iter.Current.ToString());

    while (iter.MoveNext())
    {
        writer.Write(delimiter);
        writer.Write(iter.Current.ToString());
    }
}

public static string Delimit<T>(this IEnumerable<T> me, string delimiter)
{
    var writer = new System.IO.StringWriter();
    me.Delimit(writer, delimiter);
    return writer.ToString();
}

So given prices above you'd have

decimal[] prices = { 39.99M, 29.99m, 29.99m, 19.99m, 49.99m }; 
Console.WriteLine("the prices are {0}", prices.Delimit(", "));

or

decimal[] prices = { 39.99M, 29.99m, 29.99m, 19.99m, 49.99m }; 
Console.Write("the prices are ")
prices.Delimit(System.Console.Out, ", ");
Console.WriteLine();

Upvotes: 2

Jord&#227;o
Jord&#227;o

Reputation: 56477

Picking up where ck left off, extract it to a method to make it reusable:

public static class EnumerableExtensions {
  public static string Join<T>(this IEnumerable<T> self, string separator) { 
    if (self == null) throw new ArgumentNullException();
    if (separator == null) throw new ArgumentNullException("separator");
    return String.Join(separator, self.Select(e => e.ToString()).ToArray());
  }
}

Now the usage is more readable:

Console.WriteLine("the prices are {0}", prices.Join(", "));

Upvotes: 1

Andrew
Andrew

Reputation: 423

Could use linq to translate to strings:

Console.WriteLine("the prices are {0}", String.Join(", ", prices.Select(p => p.ToString()).ToArray()));

or use Aggregate() instead of string.Join()

Console.WriteLine("the prices are {0}",
    prices.Select(p => p.ToString()).
          .Aggregate((total, p) => total + ", " + p));

or even (with slightly different formatting)

Console.WriteLine(
    prices.Select(p => p.ToString()).
          .Aggregate("the prices are", (total, p) => total + ", " + p));

Upvotes: 0

onof
onof

Reputation: 17367

Console.WriteLine("the prices are {0}", String.Join(", ", Array.ConvertAll(prices, p => p.ToString()));

Upvotes: 5

cjk
cjk

Reputation: 46435

If you have LINQ:

decimal[] prices = { 39.99M, 29.99m, 29.99m, 19.99m, 49.99m }; 
Console.WriteLine("the prices are {0}", 
    String.Join(", ", 
       prices.Select(p => p.ToString()).ToArray()
    )
);

Upvotes: 13

Related Questions