string.List <int> veya başka bir türe katılın


86

Bir dizi veya giriş listesini aşağıdaki gibi virgülle ayrılmış bir dizeye dönüştürmek istiyorum:

string myFunction(List<int> a) {
    return string.Join(",", a);
}

Ancak string.Join yalnızca List<string>ikinci parametre olarak alır . Bunu yapmanın en iyi yolu nedir?


2
C # / .NET'in hangi sürümünü kullanıyorsunuz?
Mark Byers

Yanıtlar:


149

En iyi yol, istediğinizi yapan bir aşırı yükün olduğu .NET 4.0'a yükseltmektir:

Yükseltemezseniz, aynı efekti Select ve ToArray kullanarak elde edebilirsiniz.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());

Ayrıca en azından C # 3, .NET
3.5'te

Neden yerleşik ToArrayyöntemi yerine LINQ kullanılıyor List<T>?
Steven Sudit

2
çünkü bir List <int> olurdu. Linq select List <int> değerini IEnumerable <string> 'e ve ardından diziye dönüştürür.
Greg Bogumil

4.0'a yükseltmek benim durumumda pratik değil, ancak LINQ çözümü tam olarak aradığım şeydi. Teşekkürler!
Code Commander

1
@gbogumil: Üzgünüm, bunun bir int.
Steven Sudit

5

Bir ölçeklenebilir ve güvenli bir jenerik enumerable dize uygulanması .NET 3.5 için katılın. Yineleyicilerin kullanımı, birleştirme dizesi değerinin dizenin sonunda sıkışmaması içindir. 0, 1 ve daha fazla elemanla doğru çalışır:

public static class StringExtensions
{
    public static string Join<T>(this string joinWith, IEnumerable<T> list)
    {
        if (list == null)
            throw new ArgumentNullException("list");
        if (joinWith == null)
            throw new ArgumentNullException("joinWith");

        var stringBuilder = new StringBuilder();
        var enumerator = list.GetEnumerator();

        if (!enumerator.MoveNext())
            return string.Empty;

        while (true)
        {
            stringBuilder.Append(enumerator.Current);
            if (!enumerator.MoveNext())
                break;

            stringBuilder.Append(joinWith);
        }

        return stringBuilder.ToString();
    }
}

Kullanım:

var arrayOfInts = new[] { 1, 2, 3, 4 };
Console.WriteLine(",".Join(arrayOfInts));

var listOfInts = new List<int> { 1, 2, 3, 4 };
Console.WriteLine(",".Join(listOfInts));

Zevk almak!


+1: Bu, .NET 4.0 öncesi tercih ettiğim yoldur. İnts listesinden tamamen yeni bir dizi oluşturmaktan çok daha ölçeklenebilir, böylece String.Join(String, String[])çağrılabilir. Söyleyeceğim tek şey, bu yöntemin Stringaksine bir uzantı olarak yazıldığını görmenin alışılmadık olduğu IEnumerable<String>- ben onu her zaman uzun bir uzatma yöntemi çağrıları zincirinin sonunda çağırma eğilimindeyim.
Alex Humphrey

2
Herhangi bir yardımı olacaksa fikri Python'dan çaldım!
Silinmiş

4

.NET 2.0:

static string IntListToDelimitedString(List<int> intList, char Delimiter)
{
    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < intList.Count; i++)
    {
        builder.Append(intList[i].ToString());

        if (i != intList.Count - 1)
            builder.Append(Delimiter);
    }

    return builder.ToString();
}

3
İyi bir 2.0 yaklaşımı. Yöntemin içine gömmek yerine birleştirme karakterini bir parametre yapmak isteyebilirsiniz.
Anthony Pegram

Tipik bir optimizasyon, sınırlayıcıyı test etmeden eklemek ve ardından döngüden çıktığınızda son karakteri kaldırmaktır.
Steven Sudit

@Steven - Bunu düşünüyordum, ama bunun aynı zamanda dizenin uzunluğuna da bağlı olacağını düşünüyorum (test etmeden emin değilim), bu yüzden basit bool kontrolüne bağlı kaldım.
Kyle Rosendo

Optimizasyonun yalnızca uzun dizeler için ölçülebilir olacağından şüpheleniyorum. Bunu söyledikten sonra, kısa olanlar için bile daha yavaş olacağını düşünmüyorum.
Steven Sudit

3

Buna değiştirdiğim benzer bir Uzatma Yöntemi vardı

public static class MyExtensions
{
    public static string Join(this List<int> a, string splitChar)
    {
        return string.Join(splitChar, a.Select(n => n.ToString()).ToArray());
    }
}

ve bunu böyle kullanıyorsun

var test = new List<int>() { 1, 2, 3, 4, 5 };
string s = test.Join(",");

.NET 3.5


Bunu sevdiğimden emin değilim. IEnumerable<T>zaten bir Joinyöntemi vardır ve bu yeni yöntem tamamen farklı bir işlem gerçekleştirerek kullanımını mantık dışı hale getirir. Eğer İkinci olarak, kişi bu yöntemi oluşturmak için gidiyor, devam edin ve jenerik olarak uygulanabilir olun.
Anthony Pegram

Ruby'deki dizilerdeki birleştirme yöntemini taklit eden bir hack. ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström

Ayrıca .ToString (), her zaman T'nin bir dize gösterimini döndürmez, bu yüzden bu gerçekten biraz kafa karışıklığına neden olabilir.
Jonas Elfström

2

Henüz .NET 4.0'ın derinliklerine dalmak istemiyorsanız, bu cevap tam size göre.

String.Join (), her öğe arasında belirtilen ayırıcıyı kullanarak bir dize dizisinin tüm öğelerini birleştirir.

Sözdizimi

public static string Join(
    string separator,
    params string[] value
)

Girişler Listenizi Join yöntemine geçirmek yerine, önce bir dizi dizesi oluşturmanızı öneririm.

İşte önerdiğim şey:

static string myFunction(List<int> a) {
    int[] intArray = a.ToArray();
    string[] stringArray = new string[intArray.Length];

    for (int i = 0; i < intArray.Length; i++)
    {
        stringArray[i] = intArray[i].ToString();
    }

    return string.Join(",", stringArray);
}

3
Birisi hala 2.0'deyse, bu iyi bir yaklaşımdır. Ancak intArraygereksizdir. List<int>indekslenebilir ve bir Countözelliğe sahiptir, bu da bir diziye dönüşümü gereksiz kılar. Ayrıca, birleştirme karakterini yönteme gömmek yerine bir parametre yapmak isteyebilirsiniz.
Anthony Pegram

2

.NET 4.0 kullanma

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string s = myFunction(PopulateTestList());
        this.TextBox1.Text = s;
    }

    protected List<int> PopulateTestList()
    {
        List<int> thisList = new List<int>();
        thisList.Add(22);
        thisList.Add(33);
        thisList.Add(44);

        return thisList;
    }

    protected string myFunction(List<int> a)
    {
        return string.Join(",", a);
    }
}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.