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


101

정수 배열이 있습니다.

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

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

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


3
그래서 바위! 나는 일요일에 10 분 안에이 3 개의 훌륭한 대답을 얻었다!
Riri

4
현재 .NET 4.0객체의 배열과는 IEnumerable 그냥 할 수 있도록를 취할 방법이 있습니다 string.join(",", number). 나는 질문이 .NET 3.5를 지정한다는 것을 알고 있으므로 이것을 대답하지 않았지만 버전을 지정하지 않고 4.0에서 가능하다는 것을 알면 누군가를 도울 수 있다는 것을 알고 있습니다.
Jason Goemaat 2015

답변:


162
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이 이길 것이라고 말해줍니다. :)


이것은 아마도 핵심 .NET 확장 메서드를 사용하는 가장 좋은 방법 일 것입니다. 그러나 나는 정말 string.Join ()이 ToArray () 변환을 피하기 위해 IEnumerable <string>을 받아들이기를 바랐습니다.
spoulson

누군가가 문자열을 오버로드하는 것을 막는 것은 없습니다 .IEnumerable도 가져 오기 위해 가입하십시오. ;)
Robert P

1
이것은 아마도 가장 빠른 솔루션이 아니라 가장 쉬운 솔루션 일 것입니다.
Dave Van den Eynde

9
.NET 4는 IEnumerable을 매개 변수로 허용하는 String.Join 오버로드를 제공합니다. msdn.microsoft.com/en-us/library/dd783876.aspx
Ryan Kohn

using System.Linq;필수입니다.
Gayan Weerakutti

32

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

11

두 접근 방식의 한 가지 혼합은 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"), ","));
    }
}

좋은 해결책! 프로젝션 매개 변수는 필요하지 않습니다. 더 관용적 인 x.Select (i => i.ToString ( "X")). JoinStrings ( ";") 만 작성할 수 있습니다.
JacquesB

네, 나중에 그것에 대해 생각했습니다. 때때로 모든 것을 한 번에 지정할 수있는 것이 좋지만 작업을 분할하는 것이 확실히 더 우아합니다. :)
Jon Skeet

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

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

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


5

정수 배열이 크면 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 ()을 추가한다는 것을 알 수 있습니다.

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


더 빠른 것으로 측정 했습니까? String.Join도 StringBuilder를 사용합니다.
JacquesB

예,하지만 먼저 모든 것을 이상적인 배열로 변환해야합니다. 특히 결과 문자열 작성을 시작 하기 전에 모든 변환 된 문자열을 메모리에 동시에 가져야 함을 의미 합니다.
Jon Skeet

OTOH String.Join은 StringBuilder 버퍼의 크기를 미리 계산하여 크기 조정을 방지합니다. 따라서 더 많은 메모리가 필요하더라도 더 빠를 수 있습니다.
JacquesB

5

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

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

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 요구 사항을 놓쳤습니다.


이것은 문자열로 유효하지 않습니다 .Join 메서드는 문자열 배열 만 사용합니다. 여기에서보세요 msdn.microsoft.com/en-us/library/tk0xe5h0.aspx
ppolyzos 2011

1
오버로드 된 메서드입니다. msdn.microsoft.com/en-us/library/dd988350 방금 작성한 코드를 새 콘솔 앱에 복사하고 Console.WriteLine을 추가했으며 다음과 같이 출력됩니다. 2,3,6,7
WebMasterP 2012 년

1
나는이는 .NET 4에서 사용할 수 있습니다 생각
빈드 Malviya

int 배열이 아닌 객체 배열 (또는 문자열 배열)이 필요합니다. "call is ambiguous"오류가 발생합니다.
LarryBud 2015

2

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

나는 또한 더 간단한 방법이 있다고 생각했습니다. 성능에 대해 모르고, 누구든지 (이론적) 아이디어가 있습니까?


이 솔루션은 ", 1,2,3,4,5"를 제공합니다.
Sarin

고마워, 나는 Substring(1)그것을 고치기 위해 추가 했다 (기억에서 나온 것).
무효

2

.NET 4.0에서 문자열 조인에는에 대한 오버로드가 params object[]있으므로 다음과 같이 간단합니다.

int[] ids = new int[] { 1, 2, 3 };
string.Join(",", ids);

int[] ids = new int[] { 1, 2, 3 };
System.Data.Common.DbCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM some_table WHERE id_column IN (@bla)");
cmd.CommandText = cmd.CommandText.Replace("@bla",  string.Join(",", ids));

.NET 2.0에서는 그러한 과부하가 없기 때문에 조금 더 어렵습니다. 따라서 고유 한 일반 방법이 필요합니다.

public static string JoinArray<T>(string separator, T[] inputTypeArray)
{
    string strRetValue = null;
    System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

    for (int i = 0; i < inputTypeArray.Length; ++i)
    {
        string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

        if (!string.IsNullOrEmpty(str))
        { 
            // SQL-Escape
            // if (typeof(T) == typeof(string))
            //    str = str.Replace("'", "''");

            ls.Add(str);
        } // End if (!string.IsNullOrEmpty(str))

    } // Next i 

    strRetValue= string.Join(separator, ls.ToArray());
    ls.Clear();
    ls = null;

    return strRetValue;
}

.NET 3.5에서는 확장 방법을 사용할 수 있습니다.

public static class ArrayEx
{

    public static string JoinArray<T>(this T[] inputTypeArray, string separator)
    {
        string strRetValue = null;
        System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

        for (int i = 0; i < inputTypeArray.Length; ++i)
        {
            string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

            if (!string.IsNullOrEmpty(str))
            { 
                // SQL-Escape
                // if (typeof(T) == typeof(string))
                //    str = str.Replace("'", "''");

                ls.Add(str);
            } // End if (!string.IsNullOrEmpty(str))

        } // Next i 

        strRetValue= string.Join(separator, ls.ToArray());
        ls.Clear();
        ls = null;

        return strRetValue;
    }

}

따라서 JoinArray 확장 방법을 사용할 수 있습니다.

int[] ids = new int[] { 1, 2, 3 };
string strIdList = ids.JoinArray(",");

코드에 ExtensionAttribute를 추가하면 .NET 2.0에서 해당 확장 메서드를 사용할 수도 있습니다.

// you need this once (only), and it must be in this namespace
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.