Mengonversi Daftar <int> menjadi string yang dipisahkan koma

116

Adakah cara untuk mengambil List dan mengubahnya menjadi string yang dipisahkan koma?

Saya tahu saya bisa mengulang dan membangunnya, tapi entah bagaimana menurut saya beberapa dari kalian cara yang lebih keren untuk melakukannya?

Saya benar-benar ingin mempelajari jenis 'trik' ini, jadi harap jelaskan atau tautkan ke dokumen tentang metode yang Anda gunakan.

mrblah
sumber

Jawaban:

189
List<int> list = ...;
string.Join(",", list.Select(n => n.ToString()).ToArray())
Pavel Minaev
sumber
7
Cerdas tapi lambat dan membengkak, karena mengalokasikan satu string per elemen. Menggunakan StringBuilder akan jauh lebih efisien.
Steven Sudit
3
Dari apa yang saya lihat online (pencarian cepat) String.Join lebih cepat daripada menggunakan StringBuilder.
Yuriy Faktorovich
3
stackoverflow.com/questions/585860/… , Anda salah Steven
Yuriy Faktorovich
6
Saya pikir Steven mengacu pada bagian n.ToString () daripada String.Join.
Larsenal
9
Larsenal: tetapi StringBuilder.Append (Int32) secara internal memanggil ToString pada integer. StringBuilder tidak secara ajaib menghindari biaya pengalokasian string untuk setiap elemen; itu hanya melipatnya dengan baik sehingga tidak terlihat.
itowlson
115

Solusi sederhana adalah

List<int> list = new List<int>() {1,2,3};
string.Join<int>(",", list)

Saya baru saja menggunakannya dalam kode saya, bekerja secara funtastic.

Nitin Daware
sumber
1
Terima kasih! ini adalah pendekatan yang indah
Irfan Ashraf
2
Ini adalah pendekatan yang lebih baik daripada jawaban yang diterima. Dengan pendekatan ini Anda tidak perlu mengimpor Linq dan ini lebih cepat.
JoKeRxbLaCk
Keren! Saya tidak pernah tahu string. Join memiliki kelebihan beban umum. Terima kasih.
mrmashal
10
List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(String.Join(",", list.Select(i => i.ToString()).ToArray()));
Yuriy Faktorovich
sumber
Bagus jika Anda tidak dapat menggunakan .NET 4
Greg Woods
6

Untuk sekitar satu trilyun solusi untuk versi yang sedikit lebih rumit dari masalah ini - banyak di antaranya lambat, buggy, atau bahkan tidak dapat dikompilasi - lihat komentar di artikel saya tentang hal ini:

http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-quibbling.aspx

dan komentar StackOverflow:

Tantangan Eric Lippert "quibbling koma", jawaban terbaik?

Eric Lippert
sumber
Terima kasih untuk tautannya. Masalah penggabungan string ini ternyata lebih kompleks, dan lebih mendidik, dari yang saya duga!
Steven Sudit
4

Untuk kesejukan ekstra, saya akan menjadikan ini metode ekstensi di IEnumerable <T> sehingga berfungsi pada IEnumerable mana pun:

public static class IEnumerableExtensions {
  public static string BuildString<T>(this IEnumerable<T> self, string delim = ",") {
    return string.Join(delim, self)        
  }
}

Gunakan sebagai berikut:

List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(list.BuildString(", "));
cdiggins.dll
sumber
Dua kemungkinan pengoptimalan: 1) Tambahkan pembatas setelah setiap item, lalu hapus yang ekstra setelah loop berakhir. 2) Tentukan kapasitas untuk StringBuilder.
Steven Sudit
1
Jika Anda menggali Reflektor, ternyata Join menjumlahkan panjang untuk menghitung sebelumnya ukuran buffer, dan juga "mengatur pompa" dengan menambahkan string pertama di luar loop, dan kemudian, di dalam loop, menambahkan pembatas tanpa syarat sebelum string berikutnya. Dikombinasikan dengan beberapa trik tidak aman / internal, itu harus sangat cepat.
Steven Sudit
@ Steven: ikuti saran Anda.
cdiggins
1
Anda melakukan hardcode pembatas di ekstensi Anda dan mengabaikan nilai yang diteruskan untuk pembatas, dan melewatkan titik koma. Seharusnyareturn string.Join(delim, self);
Andrew
1

Tampaknya cukup cepat.

IList<int> listItem = Enumerable.Range(0, 100000).ToList();
var result = listItem.Aggregate<int, StringBuilder, string>(new StringBuilder(), (strBuild, intVal) => { strBuild.Append(intVal); strBuild.Append(","); return strBuild; }, (strBuild) => strBuild.ToString(0, strBuild.Length - 1));
Gregory
sumber
1

Entri "pintar" saya:

        List<int> list = new List<int> { 1, 2, 3 };
        StringBuilder sb = new StringBuilder();
        var y = list.Skip(1).Aggregate(sb.Append(x.ToString()),
                    (sb1, x) =>  sb1.AppendFormat(",{0}",x));

        // A lot of mess to remove initial comma
        Console.WriteLine(y.ToString().Substring(1,y.Length - 1));

Hanya belum menemukan cara menambahkan koma secara kondisional.

Larsenal
sumber
1
Tolong jangan menulis Selectdengan efek samping di lambda. Dalam hal ini Anda bahkan tidak menggunakan y, jadi Anda Selectpada dasarnya hanya a foreach- jadi tulis seperti itu.
Pavel Minaev
Saya tidak menyarankan ini sebagai solusi yang baik. OP menginginkan sesuatu yang lebih menarik daripada foreach.
Larsenal
Ya, tapi menyalahgunakan Selectseperti foreachmelewati "menarik" dan menjadi, yah, "penyalahgunaan". Pendekatan yang lebih menarik di sini akan digunakan Enumerable.Aggregatedengan StringBuildersebagai nilai benih - coba itu.
Pavel Minaev
Ide bagus. Aku harus keluar, tapi mungkin aku akan mencobanya.
Larsenal
0

Anda dapat menggunakan, perpustakaan System.Linq; Ini lebih efisien:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
Maurico Bello
sumber