[c#] .NET에서 int []를 문자로 구분 된 문자열에 결합하는 방법은 무엇입니까?

정수 배열이 있습니다.

int[] number = new int[] { 2,3,6,7 };

숫자가 문자로 구분되는 단일 문자열로 변환하는 가장 쉬운 방법은 무엇입니까 (예 🙂 "2,3,6,7"?

저는 C # 및 .NET 3.5에 있습니다.



답변

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"

편집 : (적어도) .NET 4.5부터,

var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());

다음과 같습니다.

var result = string.Join(",", ints);

수정 :

몇 가지 솔루션이 StringBuilder 사용을 광고하는 것을 봅니다. 누군가는 Join 메서드가 IEnumerable 인수를 가져야한다고 불평합니다.

나는 당신을 실망시킬 것입니다 🙂 String.Join은 성능이라는 한 가지 이유로 배열이 필요합니다. Join 메소드는 필요한 양의 메모리를 효과적으로 사전 할당하기 위해 데이터의 크기를 알아야합니다.

다음은 String.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이 이길 것이라고 말해줍니다. 🙂


답변

OP가 .NET 3.5를 지정했지만 C # 2를 사용하여 .NET 2.0에서이 작업을 수행하려는 사람들은 다음을 수행 할 수 있습니다.

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

C # 3에서는 람다가 형식 추론에 도움이 될 수 있지만 Convert.xxx 함수를 사용하는 것이 람다에 대한 깔끔한 대안 인 다른 경우가 많이 있습니다.

.NET 2.0에서 작동하는 상당히 컴팩트 한 C # 3 버전은 다음과 같습니다.

string.Join(",", Array.ConvertAll(ints, item => item.ToString()))


답변

두 접근 방식의 한 가지 혼합은 StringBuilder를 사용하는 IEnumerable <T>에 확장 메서드를 작성하는 것입니다. 다음은 변환을 지정할지 아니면 일반 ToString에만 의존할지에 따라 다른 오버로드가있는 예입니다. 다른 유형의 Join과의 혼동을 피하기 위해 “Join”대신 “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"), ","));
    }
}


답변

String.Join(";", number.Select(item => item.ToString()).ToArray());

String결합하기 전에 각 항목을로 변환 해야하므로 Select및 람다 표현식 을 사용하는 것이 합리적 입니다. 이는 map일부 다른 언어 와 동일합니다 . 그런 다음 String.Join문자열 배열 만 허용 하므로 결과 문자열 모음을 배열로 다시 변환해야합니다 .

ToArray()내가 생각하는 약간 못생긴입니다. String.Join정말 받아 들여야 IEnumerable<String>합니다. 배열로만 제한 할 이유가 없습니다. 이것은 아마도 Join배열이 사용 가능한 유일한 유형의 컬렉션 인 제네릭 이전에 있기 때문일 것입니다 .


답변

정수 배열이 크면 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.Append (int value)”가 내부적으로 문자열 개체를 만들지 않고 정수 값의 문자열 표현을 추가 할 수 있다는 잘못된 인상을 받았습니다. 이것은 잘못된 것입니다. Reflector로 메서드를 검사하면 단순히 value.ToString ()을 추가한다는 것을 알 수 있습니다.

따라서 유일한 잠재적 인 성능 차이는이 기술이 하나의 배열 생성을 피하고 가비지 수집을 위해 문자열을 약간 더 빨리 해제한다는 것입니다. 실제로 이것은 측정 가능한 차이를 만들지 않을 것이므로 더 나은 솔루션을 추천했습니다 .


답변

문제는 “숫자가 문자로 구분되는 단일 문자열로 이들을 변환하는 가장 쉬운 방법”입니다.

가장 쉬운 방법은 다음과 같습니다.

int[] numbers = new int[] { 2,3,6,7 };
string number_string = string.Join(",", numbers);
// do whatever you want with your exciting new number string

편집 : 이것은 .NET 4.0 이상에서만 작동하며 처음 질문을 읽을 때 .NET 3.5 요구 사항을 놓쳤습니다.


답변

나는 가독성과 유지 보수성 측면에서 람다 표현에 동의하지만 항상 최선의 선택이 아닐 것입니다. 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);