Как присоединиться, интервал [] к символу разделил строку в.NET?

99
задан Mykola 19 February 2016 в 10:31
поделиться

8 ответов

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"

РЕДАКТИРОВАНИЕ :

я вижу, что несколько решений рекламируют использование StringBuilder. Кто-то жалобы, что метод Join должен взять аргумент IEnumerable.

я собираюсь разочаровать Вас:) Строка. Join требует массива по единственной причине - производительность. Метод Join должен знать, что размер данных эффективно предварительно выделяет необходимый объем памяти.

Вот часть внутренней реализации Строки. Метод Join:

// 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]);
    }
}

я слишком ленив для сравнения производительности предложенных методов. Но что-то мне подсказывает, что Join победит:)

160
ответ дан Nick Bull 24 November 2019 в 05:00
поделиться

Хотя OP определил.NET 3.5, люди, желающие сделать, это в.NET 2.0 с C#2 может сделать это:

string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));

я нахожу, что существует много других случаев, где использование функций Convert.xxx является более опрятной альтернативой лямбде, хотя в C#3 лямбда могла бы помочь выводу типа.

А довольно компактная версия C#3, которая работает с.NET 2.0, является этим:

string.Join(",", Array.ConvertAll(ints, item => item.ToString()))
32
ответ дан Will Dean 24 November 2019 в 05:00
поделиться

Одна смесь двух подходов должна была бы записать дополнительный метод на IEnumerable< T>, который использовал StringBuilder. Вот пример с различными перегрузками в зависимости от того, хотите ли Вы определить преобразование или просто полагаться на плоскость ToString. Я назвал метод "JoinStrings" вместо "Соединения" для предотвращения беспорядка с другим типом Соединения. Возможно, кто-то может придумать лучшее имя:)

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"), ","));
    }
}
11
ответ дан Jon Skeet 24 November 2019 в 05:00
поделиться
String.Join(";", number.Select(item => item.ToString()).ToArray());

Мы должны преобразовать каждый из объектов к String, прежде чем мы сможем присоединиться к ним, таким образом, имеет смысл использовать Select и лямбда-выражение. Это эквивалентно map на некоторых других языках. Тогда мы должны преобразовать получающийся набор строки назад к массиву, потому что String.Join только принимает массив строк.

Эти ToArray() немного ужасно, я думаю. String.Join должен действительно принять IEnumerable<String>, нет никакой причины ограничить его только массивами. Это, вероятно, просто, потому что Join до дженериков, когда массивы были единственным видом введенного доступного набора.

8
ответ дан JacquesB 24 November 2019 в 05:00
поделиться

Если Ваш массив целых чисел может быть большим, Вы получите лучшую производительность с помощью StringBuilder. Например:

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

Редактирование: Когда я отправил это, у меня создался ошибочное впечатление тот "StringBuilder. Добавьте (международное значение)" внутренне сумел добавить строковое представление целочисленного значения, не создавая строковый объект. Это неправильно: осмотр метода с Отражателем показывает, что это просто добавляет значение. ToString ().

Поэтому единственное потенциальное различие в производительности - то, что эта техника избегает одного создания массива и освобождает строки для сборки "мусора" немного раньше. На практике это не будет иметь никакого измеримого значения, таким образом, у меня будет upvoted это лучшее решение .

5
ответ дан Community 24 November 2019 в 05:00
поделиться

Я соглашаюсь с лямбда-выражением для удобочитаемости и пригодности для обслуживания, но это не всегда будет наилучший вариант. Оборотная сторона к использованию и IEnumerable/ToArray и подходы StringBuilder - то, что они должны динамично вырастить список, или объектов или символов, так как они не знают, сколько пространства будет необходимо для заключительной строки.

, Если редкий случай, где скорость более важна, чем краткость, следующее, более эффективен.

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);
2
ответ дан DocMax 24 November 2019 в 05:00
поделиться
1
ответ дан Ray Lu 24 November 2019 в 05:00
поделиться
ints.Aggregate("", ( str, n ) => str +","+ n ).Substring(1);

Я тоже подумал, что есть более простой способ. Не знаю о производительности, у кого-нибудь есть (теоретические) идеи?

2
ответ дан 24 November 2019 в 05:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: