2009-08-07 17 views
9

Załóżmy, że mam kolekcję strun:Generowanie oddzielonych przecinkami wartości

"foo" 
"bar" 
"xyz" 

I chciałbym wygenerować oddzielonych przecinkami wartości z listy w coś podobnego:

"foo, bar, xyz" 

zauważyć brak ", " na końcu.

Jestem świadomy, że istnieją dziesiątki sposobów, aby wygenerować to:

  • zastosowanie do pętli i string.Format() lub StringBuilder.
  • licznik użycie całkowitą i usunąć końcówkę „«jeżeli wartość> 0
  • nie umieścić»,” na pierwszym biegu
  • itp

kodu próbka tego, co mam prawo teraz:

if (strs.Count() > 0) 
{ 
    var sb = new StringBuilder(); 
    foreach (var str in strs) 
    sb.AppendFormat("{0}, ", str); 
    return sb.Remove(0, 2).ToString(); 
} 

Jaki jest najlepszy kod, który można w dużym stopniu wykorzystać w powyższym scenariuszu i dlaczego?

Odpowiedz

4

string.join jest prawidłowa odpowiedź, ale w przypadku IEnumerable, LINQ jest często krótszy niż dla pętli:

someStringCollection.Aggregate((first, second) => first + ", " + second); 
+0

Dobre wykorzystanie LINQ! –

26

Chcesz użyć metody string.Join, która istnieje w BCL do tego celu.

Przykład:

var myArray = new string[] { "one", "two", "three" }; 
var output = string.Join(", ", myArray); 

Lub jeśli używasz .NET 3.5, można to zrobić z dowolnej IEnumerable<string> jako takie:

var output = string.Join(", ", myEnumerable.ToArray()); 

(Zauważ, że to nie daje najlepszy wydajność, ponieważ wymaga, mimo że jest wyraźnie nadal "O (n)", i powinna być odpowiednia dla prawie wszystkich przypadków).

Teraz, jeśli nie jest przeliczalny typu string (ogólnie IEnumerable<T>), można po prostu użyć metody Select przekonwertować wynik na ciąg znaków, na przykład

var output = string.Join(", ", myEnumerable.Select(e => e.ToString()).ToArray()); 

Nie jestem pewien, czy masz do czynienia z wartościami, które mogą potencjalnie zawiera w sobie przecinki, ale można to obejść poprzez zamknięcie ich w cudzysłów (") i ucieczce cytaty, podobnie do formatu CSV.

var output = string.Join(", ", items.Select(x => x.Contains(",") ? 
    "\"" + x.Replace("\"", "\"\"") + "\"" : x); 

Oczywiście, dzieląc je z powrotem znowu jest nieco triciker zadanie, które wymaga trochę regex.

+1

Hmm ... Nie wiedziałem, że ta funkcja istnieje (sprawia, że ​​moje pytanie wygląda źle). –

+0

@Adrian: Bez obaw. Jeśli nie wywodzisz się z .NET, odkrywanie nowych rzeczy w ramach nie zawsze jest proste - jest to po prostu proces budowania znajomości. – Noldorin

+1

To jest problem, robię .NET od pierwszej wersji. Duh. –

2

Zastosowanie

string s = string.Join (",", new string[] {"aaa", "bbb", "ccc"}); 
3
string finalstr = String.Join(",", strs); 
0

Jeśli masz tablicę łańcuchów, iść z Noldorin „s rozwiązania.

Ale jeśli jest jakiś inny typ kolekcji, mogę to zrobić:

if (strs.Count() > 0) 
{ 
    var sb = new StringBuilder(); 
    foreach (var str in strs) 
    sb.AppendFormat("{0} {1}", (0 == sb.Length ? "" : ","), str); 
    return sb.ToString(); 
} 
4

Jak mówili inni: String.Join jest normalnie najlepszym sposobem, aby to zrobić. Ale co, jeśli masz tylko IEnumerable zamiast tablicy? Być może masz kod do wyliczenia tych, jak czytasz je z pliku przy użyciu odroczonego wykonania. W tym przypadku String.Join nie jest tak ładne, ponieważ trzeba raz wykonać pętlę nad ciągami —, aby utworzyć tablicę i raz, aby się do niej przyłączyć. W takim przypadku, chcesz czegoś więcej tak:

public static string ToDelimitedString(this IEnumerable<string> source, string delimiter) 
{ 
    string d = ""; 
    var result = new StringBuilder(); 

    foreach(string s in source) 
    { 
     result.Append(d).Append(s); 
     d = delimiter; 
    } 
    return result.ToString(); 
} 

ten wykona prawie jak string.join i działa w bardziej ogólnym przypadku. Następnie podano tablicę ciągów lub jakiegokolwiek innego IEnumerable można nazwać tak:

string finalStr = MyStrings.ToDelimitedString(","); 
+0

Tak, to chyba bardziej powszechny scenariusz. IEnumerable niż string []. –

+0

+1 "Result.Append (d) .Append (s)" jest interesujące ... nigdy nawet o tym nie pomyślałem. Byłoby miło zobaczyć, jak wiele różnych sposobów wykonuje to proste zadanie. –

+0

Naprawdę fajne jest to, że jitter zwykle optymalizuje dodatkowe zadania, więc kod robi _exactly_, co chcesz. –

Powiązane problemy