[C#] IList <string> 또는 IEnumerable <string>에서 쉼표로 구분 된 목록 작성

IList<string>또는 에서 쉼표로 구분 된 문자열 값 목록을 만드는 가장 깨끗한 방법은 무엇입니까 IEnumerable<string>?

String.Join(...)에서 작동 string[]하므로 문자열 배열로 변환 IList<string>하거나 IEnumerable<string>쉽게 변환 할 수없는 경우 작업하기가 번거로울 수 있습니다 .



답변

.NET 4 이상

IList<string> strings = new List<string>{"1","2","testing"};
string joined = string.Join(",", strings);

세부 및 사전 .Net 4.0 솔루션

IEnumerable<string>LINQ (.NET 3.5) 를 사용하면 문자열 배열로 매우 쉽게 변환 할 수 있습니다 .

IEnumerable<string> strings = ...;
string[] array = strings.ToArray();

필요한 경우 동등한 도우미 메소드를 작성하는 것이 쉽습니다.

public static T[] ToArray(IEnumerable<T> source)
{
    return new List<T>(source).ToArray();
}

그런 다음 다음과 같이 호출하십시오.

IEnumerable<string> strings = ...;
string[] array = Helpers.ToArray(strings);

그런 다음에 전화 할 수 있습니다 string.Join. 물론, 당신은하지 않습니다 도우미 메서드를 사용하여 :

// C# 3 and .NET 3.5 way:
string joined = string.Join(",", strings.ToArray());
// C# 2 and .NET 2.0 way:
string joined = string.Join(",", new List<string>(strings).ToArray());

후자는 약간 한 입입니다 🙂

에 대한 다른 질문이 성능을 포함하여 (이에 국한되지 않음)처럼 정확히 – 이것은 아주 성능이 좋은뿐만 아니라 그것을 할 수있는 간단한 방법이 될 가능성이 있으며, 이 중 하나를 .

.NET 4.0부터에서 사용할 수있는 과부하가 더 string.Join많으므로 실제로 다음과 같이 작성할 수 있습니다.

string joined = string.Join(",", strings);

훨씬 간단합니다 🙂


답변

참고로, .NET 4.0 버전의 string.Join()일부 오버로드IEnumerable배열 을 대신하여 작동 합니다 T.

public static string Join(string separator, IEnumerable<string> values)
public static string Join<T>(string separator, IEnumerable<T> values)


답변

이 작업을 수행하는 가장 쉬운 방법은 LINQ Aggregate방법을 사용하는 것입니다.

string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)


답변

쉼표로 구분 된 문자열 값 목록을 만드는 가장 깨끗한 방법은 다음과 같습니다.

string.Join<string>(",", stringEnumerable);

전체 예는 다음과 같습니다.

IEnumerable<string> stringEnumerable= new List<string>();
stringList.Add("Comma");
stringList.Add("Separated");

string.Join<string>(",", stringEnumerable);

도우미 기능을 만들 필요가 없으며 .NET 4.0 이상에 내장되어 있습니다.


답변

실적을 기준으로 비교하면 “루프, sb. 추가 및 백스텝”입니다. 실제로 “다음 열거 및 수동 이동”도 동일합니다 (stddev 고려).

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Core   : .NET Core 4.6.25009.03, 64bit RyuJIT


                Method |  Job | Runtime |     Mean |     Error |    StdDev |      Min |      Max |   Median | Rank |  Gen 0 | Allocated |
---------------------- |----- |-------- |---------:|----------:|----------:|---------:|---------:|---------:|-----:|-------:|----------:|
            StringJoin |  Clr |     Clr | 28.24 us | 0.4381 us | 0.3659 us | 27.68 us | 29.10 us | 28.21 us |    8 | 4.9969 |   16.3 kB |
 SeparatorSubstitution |  Clr |     Clr | 17.90 us | 0.2900 us | 0.2712 us | 17.55 us | 18.37 us | 17.80 us |    6 | 4.9296 |  16.27 kB |
     SeparatorStepBack |  Clr |     Clr | 16.81 us | 0.1289 us | 0.1206 us | 16.64 us | 17.05 us | 16.81 us |    2 | 4.9459 |  16.27 kB |
            Enumerable |  Clr |     Clr | 17.27 us | 0.0736 us | 0.0615 us | 17.17 us | 17.36 us | 17.29 us |    4 | 4.9377 |  16.27 kB |
            StringJoin | Core |    Core | 27.51 us | 0.5340 us | 0.4995 us | 26.80 us | 28.25 us | 27.51 us |    7 | 5.0296 |  16.26 kB |
 SeparatorSubstitution | Core |    Core | 17.37 us | 0.1664 us | 0.1557 us | 17.15 us | 17.68 us | 17.39 us |    5 | 4.9622 |  16.22 kB |
     SeparatorStepBack | Core |    Core | 15.65 us | 0.1545 us | 0.1290 us | 15.45 us | 15.82 us | 15.66 us |    1 | 4.9622 |  16.22 kB |
            Enumerable | Core |    Core | 17.00 us | 0.0905 us | 0.0654 us | 16.93 us | 17.12 us | 16.98 us |    3 | 4.9622 |  16.22 kB |

암호:

public class BenchmarkStringUnion
{
    List<string> testData = new List<string>();
    public BenchmarkStringUnion()
    {
        for(int i=0;i<1000;i++)
        {
            testData.Add(i.ToString());
        }
    }
    [Benchmark]
    public string StringJoin()
    {
        var text = string.Join<string>(",", testData);
        return text;
    }
    [Benchmark]
    public string SeparatorSubstitution()
    {
        var sb = new StringBuilder();
        var separator = String.Empty;
        foreach (var value in testData)
        {
            sb.Append(separator).Append(value);
            separator = ",";
        }
        return sb.ToString();
    }

    [Benchmark]
    public string SeparatorStepBack()
    {
        var sb = new StringBuilder();
        foreach (var item in testData)
            sb.Append(item).Append(',');
        if (sb.Length>=1)
            sb.Length--;
        return sb.ToString();
    }

    [Benchmark]
    public string Enumerable()
    {
        var sb = new StringBuilder();
        var e = testData.GetEnumerator();
        bool  moveNext = e.MoveNext();
        while (moveNext)
        {
            sb.Append(e.Current);
            moveNext = e.MoveNext();
            if (moveNext)
                sb.Append(",");
        }
        return sb.ToString();
    }
}

https://github.com/dotnet/BenchmarkDotNet 이 사용되었습니다


답변

ToString ()이 아닌 객체 목록의 특정 속성을 조인하는 동안 여기에 도달했기 때문에 여기에 허용되는 답변이 추가되었습니다.

var commaDelimited = string.Join(",", students.Where(i => i.Category == studentCategory)
                                 .Select(i => i.FirstName));


답변

다른 확장 방법은 다음과 같습니다.

    public static string Join(this IEnumerable<string> source, string separator)
    {
        return string.Join(separator, source);
    }