我有一個整數數組:如何將int []連接到.NET中的字符分隔字符串?
int[] number = new int[] { 2,3,6,7 };
什麼是將這些成一個字符串,其中數由一個字符分隔的最簡單的方法(如:"2,3,6,7"
)?
我在C#和.NET 3.5中。
我有一個整數數組:如何將int []連接到.NET中的字符分隔字符串?
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"
編輯:
我看到幾個解決方案做廣告的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]);
}
}
我懶得比較的建議方法的性能。但直覺告訴我,加入贏:)
這可能是使用核心.NET擴展方法的最佳選擇,但我真的希望string.Join()將接受IEnumerable
沒有什麼可以阻止某人重載string.Join以獲取IEnumerable。 ;) – 2008-10-20 19:57:53
這可能也是最簡單的解決方案,而不僅僅是最快的解決方案。 – 2008-10-22 10:40:43
String.Join(";", number.Select(item => item.ToString()).ToArray());
我們必須每個項目轉換爲String
纔可以加入他們的行列,所以是有意義的使用Select
和lambda表達式。這相當於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值)」內部管理要追加整數值的字符串表示不創建一個字符串對象下。這是錯誤的:用Reflector檢查方法表明它只是附加value.ToString()。
因此,唯一潛在的性能差異是這種技術避免了一個數組的創建,並且稍微更快地釋放了垃圾收集的字符串。在實踐中,這不會產生任何可衡量的差異,所以我已經upvoted this better solution。
你覺得它更快嗎? String.Join也使用StringBuilder。 – JacquesB 2008-09-28 14:37:21
是的,但你首先需要將整個事情轉換爲一個數組,這遠非理想。特別是,它意味着您需要同時在內存中存儲所有已轉換的字符串,*在開始構建結果字符串之前。 – 2008-09-28 14:46:16
這兩種方法的一種混合將是在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"), ","));
}
}
我同意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);
你可以做
ints.ToString(",")
ints.ToString("|")
ints.ToString(":")
退房
Separator Delimited ToString for Array, List, Dictionary, Generic IEnumerable
雖然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()))
ints.Aggregate("", (str, n) => str +","+ n).Substring(1);
我也想有一個簡單的方法。不知道表現,任何人都有任何(理論上的)想法?
問題是「將這些轉換爲單個字符串的最簡單方法,其中數字由字符分隔」。
最簡單的方法是:
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的要求,我第一次看這個問題。
在.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 {}
}
這樣的岩石!我在星期天的10分鐘內得到了這3個優秀的答案! – Riri 2008-09-28 13:54:49
從.NET 4.0開始,有些方法需要一個對象數組和一個IEnumerable,所以你可以'string.join(「,」,number)`。我知道這個問題指定了.NET 3.5,所以我沒有做出這個答案,但它出現在沒有指定版本的搜索中,並且知道它在4.0中可能會幫助某人。 – 2015-02-23 21:06:46