2008-09-28 50 views
87

我有一個整數數組:如何將int []連接到.NET中的字符分隔字符串?

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

什麼是將這些成一個字符串,其中數由一個字符分隔的最簡單的方法(如:"2,3,6,7")?

我在C#和.NET 3.5中。

+2

這樣的岩石!我在星期天的10分鐘內得到了這3個優秀的答案! – Riri 2008-09-28 13:54:49

+3

從.NET 4.0開始,有些方法需要一個對象數組和一個IEnumerable,所以你可以'string.join(「,」,number)`。我知道這個問題指定了.NET 3.5,所以我沒有做出這個答案,但它出現在沒有指定版本的搜索中,並且知道它在4.0中可能會幫助某人。 – 2015-02-23 21:06:46

回答

144
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參數。

我會讓你失望:) 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]); 
    } 
} 

我懶得比較的建議方法的性能。但直覺告訴我,加入贏:)

+0

這可能是使用核心.NET擴展方法的最佳選擇,但我真的希望string.Join()將接受IEnumerable 以避免ToArray()轉換。 – spoulson 2008-09-28 14:43:25

+0

沒有什麼可以阻止某人重載string.Join以獲取IEnumerable。 ;) – 2008-10-20 19:57:53

+1

這可能也是最簡單的解決方案,而不僅僅是最快的解決方案。 – 2008-10-22 10:40:43

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

我們必須每個項目轉換爲String纔可以加入他們的行列,所以是有意義的使用Select和lambda表達式。這相當於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值)」內部管理要追加整數值的字符串表示不創建一個字符串對象下。這是錯誤的:用Reflector檢查方法表明它只是附加value.ToString()。

因此,唯一潛在的性能差異是這種技術避免了一個數組的創建,並且稍微更快地釋放了垃圾收集的字符串。在實踐中,這不會產生任何可衡量的差異,所以我已經upvoted this better solution

+0

你覺得它更快嗎? String.Join也使用StringBuilder。 – JacquesB 2008-09-28 14:37:21

+0

是的,但你首先需要將整個事情轉換爲一個數組,這遠非理想。特別是,它意味着您需要同時在內存中存儲所有已轉換的字符串,*在開始構建結果字符串之前。 – 2008-09-28 14:46:16

10

這兩種方法的一種混合將是在IEnumerable < T>上使用StringBuilder編寫擴展方法。下面是一個示例,根據您是要指定轉換還是僅依賴於簡單的ToString,具有不同的重載。我已經命名方法「JoinStrings」而不是「Join」來避免與其他類型的Join混淆。也許有人可以想出一個更好的名字:)

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"), ",")); 
    } 
} 
2

我同意lambda表達式的可讀性和可維護性,但它並不總是最好的選擇。使用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); 
32

雖然OP指定的.NET 3.5,人想這樣做在.NET 2.0與C#2能做到這一點:

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

我發現有很多其他的情況,其中使用Convert.xxx函數是lambda的更好選擇,儘管在C#3中lambda可能有助於類型推斷。

一個相當緊湊的C#3.0版本與.NET 2.0的工作原理是這樣的:

string.Join(",", Array.ConvertAll(ints, item => item.ToString())) 
2
ints.Aggregate("", (str, n) => str +","+ n).Substring(1); 

我也想有一個簡單的方法。不知道表現,任何人都有任何(理論上的)想法?

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的要求,我第一次看這個問題。

1

在.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(","); 

您也可以在.NET 2中使用該擴展方法。0,如果您將ExtensionAttribute添加到您的代碼中:

// 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 {} 
} 
相關問題