Membuat daftar dipisahkan koma dari IList atau IEnumerable

Apa yang terbersih cara untuk membuat daftar dipisahkan koma nilai string dari sebuah IList<string> atau IEnumerable<string>?

String.Bergabung(...) beroperasi string[] sehingga dapat menjadi rumit untuk bekerja dengan ketika jenis seperti IList<string> atau IEnumerable<string> tidak dapat dengan mudah diubah menjadi array string.

Mengomentari pertanyaan (2)
Larutan

.NET 4+

IList strings = new List{"1","2","testing"};
string joined = string.Join(",", strings);

Detail & Pre .Net 4.0 Solusi

IEnumerable<string> dapat dikonversi menjadi string array *sangat mudah dengan LINQ (.NET 3.5):

IEnumerable strings = ...;
string[] array = strings.ToArray();

It's cukup mudah untuk menulis setara dengan metode penolong jika anda perlu untuk:

public static T[] ToArray(IEnumerable source)
{
    return new List(source).ToArray();
}

Kemudian menyebutnya seperti ini:

IEnumerable strings = ...;
string[] array = Helpers.ToArray(strings);

Anda kemudian dapat memanggil string.Bergabung. Tentu saja, anda don't memiliki untuk menggunakan metode penolong:

// C# 3 and .NET 3.5 way:
string joined = string.Join(",", strings.ToArray());
// C# 2 and .NET 2.0 way:
string joined = string.Join(",", new List(strings).ToArray());

Yang terakhir ini sedikit seteguk sekalipun :)

Ini mungkin cara paling sederhana untuk melakukannya, dan sangat performant juga - ada pertanyaan lain tentang apa kinerja yang suka, termasuk (namun tidak terbatas pada) ini.

Sebagai dari .NET 4.0, ada lebih overloads tersedia di string.Bergabung, sehingga anda dapat benar-benar hanya menulis:

string joined = string.Join(",", strings);

Jauh lebih sederhana :)

Komentar (6)

FYI,.NET versi 4.0 dari string.Join() memiliki beberapa extra overload, yang bekerja dengan IEnumerable bukan hanya array, termasuk salah satu yang dapat menangani semua jenis T:

public static string Join(string separator, IEnumerable values)
public static string Join(string separator, IEnumerable values)
Komentar (5)

Cara termudah yang saya bisa melihat untuk melakukan hal ini adalah dengan menggunakan LINQ Agregat metode:

string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)
Komentar (7)

Saya berpikir bahwa terbersih cara untuk membuat daftar dipisahkan koma nilai string adalah sederhana:

string.Join(",", stringEnumerable);

Berikut adalah contoh:

IEnumerable stringEnumerable= new List();
stringList.Add("Comma");
stringList.Add("Separated");

string.Join(",", stringEnumerable);

Ada tidak perlu untuk membuat fungsi pembantu, hotel yang dibangun ke .NET 4.0 dan di atas.

Komentar (2)

Membandingkan dengan kinerja pemenangnya adalah "Lingkaran itu, sb.Menambahkan hal itu, dan lakukan kembali langkah". Sebenarnya "enumerable dan panduan langkah berikutnya" adalah sama baik (mempertimbangkan stddev).

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Core   : .NET Core 4.6.25009.03, 64bit RyuJIT

                Method |  Job | Runtime |     Mean |     Error |    StdDev |      Min |      Max |   Median | Rank |  Gen 0 | Allocated |
---------------------- |----- |-------- |---------:|----------:|----------:|---------:|---------:|---------:|-----:|-------:|----------:|
            StringJoin |  Clr |     Clr | 28.24 us | 0.4381 us | 0.3659 us | 27.68 us | 29.10 us | 28.21 us |    8 | 4.9969 |   16.3 kB |
 SeparatorSubstitution |  Clr |     Clr | 17.90 us | 0.2900 us | 0.2712 us | 17.55 us | 18.37 us | 17.80 us |    6 | 4.9296 |  16.27 kB |
     SeparatorStepBack |  Clr |     Clr | 16.81 us | 0.1289 us | 0.1206 us | 16.64 us | 17.05 us | 16.81 us |    2 | 4.9459 |  16.27 kB |
            Enumerable |  Clr |     Clr | 17.27 us | 0.0736 us | 0.0615 us | 17.17 us | 17.36 us | 17.29 us |    4 | 4.9377 |  16.27 kB |
            StringJoin | Core |    Core | 27.51 us | 0.5340 us | 0.4995 us | 26.80 us | 28.25 us | 27.51 us |    7 | 5.0296 |  16.26 kB |
 SeparatorSubstitution | Core |    Core | 17.37 us | 0.1664 us | 0.1557 us | 17.15 us | 17.68 us | 17.39 us |    5 | 4.9622 |  16.22 kB |
     SeparatorStepBack | Core |    Core | 15.65 us | 0.1545 us | 0.1290 us | 15.45 us | 15.82 us | 15.66 us |    1 | 4.9622 |  16.22 kB |
            Enumerable | Core |    Core | 17.00 us | 0.0905 us | 0.0654 us | 16.93 us | 17.12 us | 16.98 us |    3 | 4.9622 |  16.22 kB |

Kode:

public class BenchmarkStringUnion
{
    List testData = new List();
    public BenchmarkStringUnion()
    {
        for(int i=0;i=1) 
            sb.Length--;
        return sb.ToString();
    }

    [Benchmark]
    public string Enumerable()
    {
        var sb = new StringBuilder();
        var e = testData.GetEnumerator();
        bool  moveNext = e.MoveNext();
        while (moveNext)
        {
            sb.Append(e.Current);
            moveNext = e.MoveNext();
            if (moveNext) 
                sb.Append(",");
        }
        return sb.ToString();
    }
}

https://github.com/dotnet/BenchmarkDotNet digunakan

Komentar (0)

Sejak saya sampai di sini sementara mencari untuk bergabung pada properti tertentu dari daftar benda-benda (dan tidak ToString() itu) di sini's untuk jawaban yang diterima:

var commaDelimited = string.Join(",", students.Where(i => i.Category == studentCategory)
                                 .Select(i => i.FirstName));
Komentar (0)

Berikut ini's ekstensi lain metode:

    public static string Join(this IEnumerable source, string separator)
    {
        return string.Join(separator, source);
    }
Komentar (0)

Tiba sedikit terlambat untuk diskusi ini tapi ini adalah kontribusi saya fwiw. Saya memiliki sebuah IList<I> OrderIds akan dikonversi ke CSV string tapi berikut adalah generik dan bekerja dimodifikasi dengan jenis lain:

string csv = OrderIds.Aggregate(new StringBuilder(),
             (sb, v) => sb.Append(v).Append(","),
             sb => {if (0 < sb.Length) sb.Length--; return sb.ToString();});

Pendek dan manis, menggunakan StringBuilder untuk membangun new string, menyusut StringBuilder panjang per satu untuk menghapus koma terakhir dan kembali CSV string.

I've ini diperbarui untuk menggunakan beberapa Append()'s untuk menambahkan string + koma. Dari James' umpan balik yang saya digunakan Reflektor untuk melihat StringBuilder.AppendFormat(). Ternyata AppendFormat() menggunakan StringBuilder untuk membangun format string yang membuatnya kurang efisien dalam konteks ini daripada hanya menggunakan beberapa Menambahkan()'s.

Komentar (6)

Sesuatu yang sedikit jelek, tapi itu bekerja:

string divisionsCSV = String.Join(",", ((List)divisions).ConvertAll(d => d.DivisionID.ToString("b")).ToArray());

Memberikan anda CSV dari Daftar setelah anda memberikan converter (dalam hal ini d => d.DivisionID.ToString("b")).

Hacky tapi karya - karya yang bisa dibuat menjadi sebuah metode penyuluhan mungkin?

Komentar (0)

Kebutuhan spesifik ketika kita harus mengelilingi oleh ', oleh ex:

        string[] arr = { "jj", "laa", "123" };
        List myList = arr.ToList();

        // 'jj', 'laa', '123'
        Console.WriteLine(string.Join(", ",
            myList.ConvertAll(m =>
                string.Format("'{0}'", m)).ToArray()));
Komentar (0)

Berikut ini's cara yang saya lakukan itu, dengan menggunakan cara yang telah saya lakukan itu dalam bahasa lain:

private string ToStringList(IEnumerable list, string delimiter)
{
  var sb = new StringBuilder();
  string separator = String.Empty;
  foreach (T value in list)
  {
    sb.Append(separator).Append(value);
    separator = delimiter;
  }
  return sb.ToString();
}
Komentar (0)

Kita memiliki sebuah fungsi utilitas, sesuatu seperti ini:

public static string Join( string delimiter, 
    IEnumerable collection, Func convert )
{
    return string.Join( delimiter, 
        collection.Select( convert ).ToArray() );
}

Yang dapat digunakan untuk bergabung dengan banyak koleksi dengan mudah:

int[] ids = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233};

string csv = StringUtility.Join(",", ids, i => i.ToString() );

Perhatikan bahwa kita memiliki koleksi param sebelum lambda karena intellisense kemudian mengambil jenis koleksi.

Jika anda sudah memiliki sebuah enumerasi string semua yang perlu anda lakukan adalah ToArray:

string csv = string.Join( ",", myStrings.ToArray() );
Komentar (2)

Jawaban saya adalah seperti di atas Agregat solusi tapi harus kurang panggilan-tumpukan berat karena tidak ada eksplisit delegasi panggilan:

public static string ToCommaDelimitedString(this IEnumerable items)
{
    StringBuilder sb = new StringBuilder();
    foreach (var item in items)
    {
        sb.Append(item.ToString());
        sb.Append(',');
    }
    if (sb.Length >= 1) sb.Length--;
    return sb.ToString();
}

Tentu saja, seseorang dapat memperpanjang tanda tangan untuk menjadi pembatas-independen. I'm benar-benar bukan penggemar sb.Hapus() call dan I'd seperti untuk refactor itu menjadi lurus-up sementara loop di atas IEnumerable dan menggunakan MoveNext() untuk menentukan apakah atau tidak untuk menulis koma. I'll bermain-main di sekitar dan di post itu solusi jika aku datang pada saat itu.


Berikut ini's apa yang saya inginkan awalnya:

public static string ToDelimitedString(this IEnumerable source, string delimiter, Func converter)
{
    StringBuilder sb = new StringBuilder();
    var en = source.GetEnumerator();
    bool notdone = en.MoveNext();
    while (notdone)
    {
        sb.Append(converter(en.Current));
        notdone = en.MoveNext();
        if (notdone) sb.Append(delimiter);
    }
    return sb.ToString();
}

Ada sementara array atau list bagasi yang diperlukan dan tidak ada StringBuilder Remove() atau Panjang-- hack diperlukan.

Dalam kerangka perpustakaan saya membuat beberapa variasi pada metode ini tanda tangan, setiap kombinasi termasuk pembatas dan converter parameter dengan penggunaan "," dan x.ToString() sebagai default, masing-masing.

Komentar (0)

Mereka dapat dengan mudah dikonversi ke array menggunakan Linq ekstensi .NET 3.5.

   var stringArray = stringList.ToArray();
Komentar (0)

anda dapat mengkonversi IList untuk menggunakan array ToArray dan kemudian menjalankan sebuah string.bergabung perintah pada array.

Dim strs As New List(Of String)
Dim arr As Array
arr = strs.ToArray
Komentar (0)

Mudah-mudahan ini adalah cara paling sederhana

 string Commaseplist;
 string[] itemList = { "Test1", "Test2", "Test3" };
 Commaseplist = string.join(",",itemList);
 Console.WriteLine(Commaseplist); //Outputs Test1,Test2,Test3
Komentar (0)

Aku baru saja menyelesaikan masalah ini sebelum terjadi di artikel ini. Solusi saya pergi sesuatu seperti di bawah ini :

   private static string GetSeparator(IList list, T item)
   {
       return (list.IndexOf(item) == list.Count - 1) ? "" : ", ";
   }

Disebut seperti:

List myThings;
string tidyString;

foreach (var thing in myThings)
{
     tidyString += string.format("Thing {0} is a {1}", thing.id, thing.name) + GetSeparator(myThings, thing);
}

Saya juga bisa saja dengan mudah menyatakan seperti itu dan juga telah lebih efisien:

string.Join(“,”, myThings.Select(t => string.format(“Thing {0} is a {1}”, t.id, t.name)); 
Komentar (0)

Aku datang atas diskusi ini sambil mencari yang baik C# metode untuk bergabung dengan string seperti itu dilakukan dengan MySql metode CONCAT_WS(). Metode ini berbeda dari string.Join() metode dalam hal itu tidak menambahkan tanda pemisah jika string NULL atau kosong.

CONCAT_WS(', ',tbl.Lastname,tbl.Nama depan)

akan kembali hanya Lastname jika nama depan kosong, sementara

string.Bergabung(", ", strLastname, strFirstname)

akan kembali strLastname + ", " dalam kasus yang sama.

Ingin pertama perilaku, aku menulis metode berikut:

    public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string strA, string strB, string strC = "")
    {
        return JoinStringsIfNotNullOrEmpty(strSeparator, new[] {strA, strB, strC});
    }

    public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string[] arrayStrings)
    {
        if (strSeparator == null)
            strSeparator = "";
        if (arrayStrings == null)
            return "";
        string strRetVal = arrayStrings.Where(str => !string.IsNullOrEmpty(str)).Aggregate("", (current, str) => current + (str + strSeparator));
        int trimEndStartIndex = strRetVal.Length - strSeparator.Length;
        if (trimEndStartIndex>0)
            strRetVal = strRetVal.Remove(trimEndStartIndex);
        return strRetVal;
    }
Komentar (0)

Anda juga bisa menggunakan sesuatu seperti berikut setelah anda telah dikonversi ke array menggunakan salah satu dari metode yang terdaftar oleh orang lain:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Configuration;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
            string[] itemList = { "Test1", "Test2", "Test3" };
            commaStr.AddRange(itemList);
            Console.WriteLine(commaStr.ToString()); //Outputs Test1,Test2,Test3
            Console.ReadLine();
        }
    }
}

Edit: di Sini adalah contoh lain

Komentar (0)

Saya menulis beberapa metode ekstensi untuk melakukannya dengan cara yang's efisien:

    public static string JoinWithDelimiter(this IEnumerable that, string delim) {
        var sb = new StringBuilder();
        foreach (var s in that) {
            sb.AppendToList(s,delim);
        }

        return sb.ToString();
    }

Hal ini tergantung pada

    public static string AppendToList(this String s, string item, string delim) {
        if (s.Length == 0) {
            return item;
        }

        return s+delim+item;
    }
Komentar (1)