Bir dizi tam sayıya sahibim:
int[] number = new int[] { 2,3,6,7 };
Bunları sayıların bir karakterle ayrıldığı tek bir dizeye dönüştürmenin en kolay yolu nedir (örneğin:) "2,3,6,7"
?
C # ve .NET 3.5 içindeyim.
Bir dizi tam sayıya sahibim:
int[] number = new int[] { 2,3,6,7 };
Bunları sayıların bir karakterle ayrıldığı tek bir dizeye dönüştürmenin en kolay yolu nedir (örneğin:) "2,3,6,7"
?
C # ve .NET 3.5 içindeyim.
.NET 4.0
nesneler dizisi ve bir IEnumerable sadece bunu yapabilirsiniz almak yöntem vardır string.join(",", number)
. Sorunun .NET 3.5'i belirttiğini biliyorum, bu yüzden bunu bir yanıt yapmadım, ancak bir sürüm belirtmeyen aramalarda ortaya çıkıyor ve 4.0'da mümkün olduğunu bilmek birisine yardımcı olabilir.
Yanıtlar:
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"
DÜZENLEME : (en azından) .NET 4.5 itibariyle,
var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());
eşdeğerdir:
var result = string.Join(",", ints);
DÜZENLE :
Birkaç çözümün StringBuilder kullanımının reklamını yaptığını görüyorum. Birisi Join yönteminin bir IEnumerable bağımsız değişkeni alması gerektiğinden şikayet ediyor.
Seni hayal kırıklığına uğratacağım :) String.Join tek bir nedenden dolayı dizi gerektirir - performans. Birleştirme yönteminin, gerekli bellek miktarını etkin bir şekilde önceden tahsis etmek için verilerin boyutunu bilmesi gerekir.
String.Join yönteminin dahili uygulamasının bir parçası:
// 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]);
}
}
Önerilen yöntemlerin performansını karşılaştırmak için çok tembelim. Ama bir şey bana Join'in kazanacağını söylüyor :)
using System.Linq;
gerekli.
OP, .NET 3.5'i belirtmesine rağmen, bunu C # 2 ile .NET 2.0'da yapmak isteyen kişiler bunu yapabilir:
string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));
Convert.xxx işlevlerinin kullanımının lambda'ya daha iyi bir alternatif olduğu bir dizi başka durum olduğunu buldum, ancak C # 3'te lambda tür çıkarımına yardımcı olabilir.
NET 2.0 ile çalışan oldukça kompakt bir C # 3 sürümü şudur:
string.Join(",", Array.ConvertAll(ints, item => item.ToString()))
İki yaklaşımın bir karışımı, StringBuilder kullanan IEnumerable <T> üzerine bir uzantı yöntemi yazmak olacaktır. Dönüşümü belirtmek isteyip istemediğinize veya yalnızca düz ToString'e güvenip güvenmediğinize bağlı olarak farklı aşırı yüklemelere sahip bir örnek aşağıda verilmiştir. Diğer Join türüyle karışıklığı önlemek için "Join" yerine "JoinStrings" yöntemini adlandırdım. Belki birisi daha iyi bir isim bulabilir :)
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());
Birleştirmeden String
önce öğelerin her birini a'ya dönüştürmeliyiz , bu yüzden kullanmak mantıklı Select
ve bir lambda ifadesi. Bu, map
diğer bazı dillerdeki ile eşdeğerdir . Daha sonra, sonuçta ortaya çıkan dizge koleksiyonunu bir diziye dönüştürmemiz gerekir, çünkü String.Join
yalnızca bir dizge dizisini kabul eder.
ToArray()
Bence biraz çirkin. String.Join
gerçekten kabul etmelisiniz IEnumerable<String>
, onu yalnızca dizilerle sınırlamak için hiçbir neden yoktur. Bunun nedeni büyük olasılıkla Join
, dizilerin mevcut olan tek tür koleksiyon türü olduğu zaman jeneriklerden önce gelmesidir.
Tamsayı diziniz büyükse, bir StringBuilder kullanarak daha iyi performans elde edersiniz. Örneğin:
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();
Düzenleme: Bunu yayınladığımda, "StringBuilder.Append (int value)" ifadesinin dahili olarak bir dize nesnesi oluşturmadan tamsayı değerinin dize temsilini eklemeyi başardığı yanlış izlenimi altındaydım. Bu yanlış: Yöntemi Reflector ile incelemek, basitçe value.ToString () eklediğini gösterir.
Bu nedenle, tek potansiyel performans farkı, bu tekniğin bir dizi oluşturmadan kaçınması ve dizeleri çöp toplama için biraz daha erken serbest bırakmasıdır. Pratikte bu ölçülebilir bir fark yaratmayacak, bu yüzden bu daha iyi çözüme oy verdim .
Soru, "bunları sayının bir karakterle ayrıldığı tek bir dizeye dönüştürmenin en kolay yolu" içindir.
En kolay yol şudur:
int[] numbers = new int[] { 2,3,6,7 };
string number_string = string.Join(",", numbers);
// do whatever you want with your exciting new number string
DÜZENLEME: Bu yalnızca .NET 4.0+ ile çalışır, soruyu ilk okuduğumda .NET 3.5 gereksinimini kaçırdım.
Okunabilirlik ve sürdürülebilirlik için lambda ifadesine katılıyorum, ancak bu her zaman en iyi seçenek olmayacak. Hem IEnumerable / ToArray hem de StringBuilder yaklaşımlarını kullanmanın dezavantajı, son dize için ne kadar alana ihtiyaç duyulacağını bilmediklerinden, öğelerden veya karakterlerden oluşan bir listeyi dinamik olarak büyütmek zorunda olmalarıdır.
Hızın özlü olmaktan daha önemli olduğu nadir bir durumsa, aşağıdaki daha etkilidir.
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);
.NET 4.0'da, dize birleştirmenin bir aşırı yüklemesi vardır params object[]
, bu nedenle şu kadar basittir:
int[] ids = new int[] { 1, 2, 3 };
string.Join(",", ids);
misal
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'da böyle bir aşırı yükleme olmadığı için biraz daha zordur. Yani kendi genel yönteminize ihtiyacınız var:
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'te, uzantı yöntemlerini kullanabilirsiniz:
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;
}
}
Böylece JoinArray uzantı yöntemini kullanabilirsiniz.
int[] ids = new int[] { 1, 2, 3 };
string strIdList = ids.JoinArray(",");
ExtensionAttribute'u kodunuza eklerseniz, bu uzantı yöntemini .NET 2.0'da da kullanabilirsiniz:
// 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 {}
}
Yapabilirsin
ints.ToString(",")
ints.ToString("|")
ints.ToString(":")
Çıkış yapmak
Array, List, Dictionary, Generic IEnumerable için Ayırıcı Sınırlandırılmış Hedef Dizesi