Apa cara paling efisien untuk menulis old-school:
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
... di LINQ?
c#
linq
string-concatenation
tags2k
sumber
sumber
Jawaban:
Jawaban ini menunjukkan penggunaan LINQ (
Aggregate
) seperti yang diminta dalam pertanyaan dan tidak dimaksudkan untuk penggunaan sehari-hari. Karena ini tidak menggunakanStringBuilder
itu akan memiliki kinerja yang mengerikan untuk urutan yang sangat lama. Untuk penggunaan kode biasaString.Join
seperti yang ditunjukkan pada jawaban lainnyaGunakan kueri agregat seperti ini:
Output ini:
Agregat adalah fungsi yang mengambil koleksi nilai dan mengembalikan nilai skalar. Contoh dari T-SQL termasuk min, max, dan jumlah. Baik VB dan C # memiliki dukungan untuk agregat. Baik agregat dukungan VB dan C # sebagai metode ekstensi. Menggunakan notasi titik, seseorang cukup memanggil metode pada objek IEnumerable .
Ingat bahwa permintaan agregat dieksekusi segera.
Informasi lebih lanjut - MSDN: Kueri Agregat
Jika Anda benar-benar ingin
Aggregate
menggunakan varian gunakanStringBuilder
diusulkan dalam komentar oleh CodeMonkeyKing yang akan menjadi kode yang sama seperti biasaString.Join
termasuk kinerja yang baik untuk sejumlah besar objek:sumber
""
, nilai pertama yang digunakancurrent
adalah string kosong. Jadi, untuk 1 elemen atau lebih, Anda akan selalu mendapatkan,
di awal string.Di .Net 4, ada kelebihan baru untuk
string.Join
menerima ituIEnumerable<string>
. Kode tersebut kemudian akan terlihat seperti:sumber
Mengapa menggunakan Linq?
Itu bekerja dengan sempurna dan menerima
IEnumerable<string>
sejauh yang saya ingat. Tidak perluAggregate
apa pun di sini yang jauh lebih lambat.sumber
String.Join(",", s.ToArray())
menggunakan versi yang lebih lama.Sudahkah Anda melihat metode ekstensi Agregat?
sumber
Contoh nyata dari kode saya:
Kueri adalah objek yang memiliki properti Nama yang merupakan string, dan saya ingin nama semua kueri pada daftar yang dipilih, dipisahkan dengan koma.
sumber
Inilah pendekatan gabungan Bergabung / Linq yang saya selesaikan setelah melihat jawaban lain dan masalah yang dibahas dalam pertanyaan serupa (yaitu bahwa Agregat dan Gabungan gagal dengan 0 elemen).
string Result = String.Join(",", split.Select(s => s.Name));
atau (jika
s
bukan string)string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
) untuk diimplementasikanDan tentu saja Bergabunglah mengurus koma akhir sial yang kadang-kadang menyelinap ke pendekatan lain (
for
,foreach
), itulah sebabnya saya mencari solusi Linq di tempat pertama.sumber
.Select()
seperti ini menyediakan tempat yang mudah untuk memodifikasi setiap elemen selama operasi ini. Misalnya, membungkus setiap item dalam beberapa karakter sepertistring Result = String.Join(",", split.Select(s => "'" + s + "'"));
Anda dapat menggunakan
StringBuilder
diAggregate
:(Ada
Select
di sana hanya untuk menunjukkan Anda dapat melakukan lebih banyak hal LINQ.)sumber
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
if (length > 0)
linq dan dengan mengeluarkannya.new[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
data kinerja cepat untuk kasus StringBuilder vs Select & Aggregate lebih dari 3000 elemen:
Uji unit - Durasi (detik)
LINQ_StringBuilder - 0,0036644
LINQ_Select.Aggregate - 1.8012535
sumber
Saya selalu menggunakan metode ekstensi:
sumber
string.Join
di .net 4 sudah bisa mengambilIEnumerable<T>
untuk sembarangT
.Dengan ' cara LINQ super keren ' Anda mungkin berbicara tentang cara LINQ membuat pemrograman fungsional jauh lebih cocok dengan penggunaan metode ekstensi. Maksud saya, gula sintaksis yang memungkinkan fungsi dirantai dalam cara yang linier secara visual (satu demi satu) alih-alih bersarang (satu di dalam yang lain). Sebagai contoh:
dapat ditulis seperti ini:
Anda dapat melihat bagaimana contoh kedua lebih mudah dibaca. Anda juga dapat melihat bagaimana lebih banyak fungsi dapat ditambahkan dengan lebih sedikit masalah indentasi atau Lispy parens penutup muncul di akhir ekspresi.
Banyak jawaban lain menyatakan bahwa itu
String.Join
adalah cara untuk pergi karena ini adalah yang tercepat atau paling sederhana untuk dibaca. Tetapi jika Anda mengambil interpretasi saya tentang ' cara LINQ yang sangat keren ' maka jawabannya adalah menggunakanString.Join
tetapi membungkusnya dengan metode ekstensi gaya LINQ yang akan memungkinkan Anda untuk menghubungkan fungsi Anda dengan cara yang menyenangkan secara visual. Jadi, jika Anda ingin menulis,sa.Concatenate(", ")
Anda hanya perlu membuat sesuatu seperti ini:Ini akan memberikan kode yang sama berkinerja dengan panggilan langsung (setidaknya dalam hal kompleksitas algoritma) dan dalam beberapa kasus dapat membuat kode lebih mudah dibaca (tergantung pada konteksnya) terutama jika kode lain dalam blok menggunakan gaya fungsi berantai .
sumber
Ada berbagai alternatif jawaban pada pertanyaan sebelumnya - yang memang menargetkan penargetan bilangan bulat sebagai sumber, tetapi menerima jawaban umum.
sumber
Ini dia menggunakan LINQ murni sebagai ekspresi tunggal:
Dan itu sangat cepat!
sumber
Saya akan menipu sedikit dan membuang jawaban baru untuk ini yang tampaknya meringkas yang terbaik dari semua yang ada di sini alih-alih menempelkannya di dalam komentar.
Jadi Anda dapat satu baris ini:
Sunting: Anda akan ingin memeriksa enumerable kosong terlebih dahulu atau menambahkan
.Replace("\a",string.Empty);
ke akhir ekspresi. Kurasa aku mungkin mencoba menjadi sedikit terlalu pintar.Jawaban dari @ a.friend mungkin sedikit lebih berkinerja, saya tidak yakin apa yang Replace lakukan di bawah tenda dibandingkan dengan Hapus. Satu-satunya peringatan lain jika beberapa alasan Anda ingin menyelesaikan string yang berakhir dengan Anda akan kehilangan pemisah Anda ... Saya menemukan itu tidak mungkin. Jika itu masalahnya Anda memiliki karakter mewah lain untuk dipilih.
sumber
Anda dapat menggabungkan LINQ dan
string.join()
cukup efektif. Di sini saya menghapus item dari string. Ada juga cara yang lebih baik untuk melakukan ini, tetapi ini dia:sumber
Banyak pilihan di sini. Anda dapat menggunakan LINQ dan StringBuilder sehingga Anda mendapatkan kinerja juga seperti itu:
sumber
builder.Length > 0
ForEach dan dengan menghapus koma pertama setelahSaya melakukan hal berikut dengan cepat dan kotor ketika mem-parsing file log IIS menggunakan LINQ, itu berhasil @ 1 juta baris cukup baik (15 detik), meskipun mendapat kesalahan memori ketika mencoba 2 juta baris.
Alasan sebenarnya saya menggunakan LINQ adalah untuk Distinct () yang saya butuhkan sebelumnya:
sumber
Saya membuat blog tentang ini beberapa waktu yang lalu, apa yang saya lakukan sesuai dengan apa yang Anda cari:
http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html
Dalam posting blog menjelaskan cara menerapkan metode ekstensi yang berfungsi di IEnumerable dan diberi nama Concatenate, ini akan memungkinkan Anda menulis hal-hal seperti:
Atau lebih banyak hal rumit seperti:
sumber