Каков наилучший способ String.Join для нестрокового массива? - PullRequest
5 голосов
/ 06 июля 2010

Что такое сокращенный способ для String.Join в нестроковый массив, как во втором примере?

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

Ответы [ 5 ]

13 голосов
/ 06 июля 2010

Если у вас есть 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()
    )
);
4 голосов
/ 06 июля 2010
Console.WriteLine("the prices are {0}", String.Join(", ", Array.ConvertAll(prices, p => p.ToString()));
2 голосов
/ 06 июля 2010

У меня есть две Delimit функции, которые делают это для меня.
Они занимают очень мало места: второй массив не создается, а при возвращении строки используется StringBuilder под обложками, поэтому он не копирует и не объединяет одну и ту же строку, вызывая более длительные задержки конкатенации. Как таковые, они полезны для серий очень большой и / или неизвестной длины.

Фрист пишет в TextWriter и ничего не возвращает, вторая возвращает строку и делегирует первой передаче в 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();
}

Таким образом, учитывая цены выше, вы бы

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

или

decimal[] prices = { 39.99M, 29.99m, 29.99m, 19.99m, 49.99m }; 
Console.Write("the prices are ")
prices.Delimit(System.Console.Out, ", ");
Console.WriteLine();
1 голос
/ 06 июля 2010

Подбирая, где ck остановился, извлеките его методом, чтобы сделать его многоразовым:

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());
  }
}

Теперь использование более читабельно:

Console.WriteLine("the prices are {0}", prices.Join(", "));
0 голосов
/ 06 июля 2010

Можно использовать linq для перевода в строки:

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

или используйте Aggregate () вместо string.Join ()

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

или даже (с немного другим форматированием)

Console.WriteLine(
    prices.Select(p => p.ToString()).
          .Aggregate("the prices are", (total, p) => total + ", " + p));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...