2009-08-07 8 views
9

Supongamos que tengo una colección de cadenas:Generación de valores separados por comas

"foo" 
"bar" 
"xyz" 

Y me gustaría para generar valores separados por una coma de la lista en algo así como:

"foo, bar, xyz" 

aviso de la falta de ", " al final.

Soy consciente de que hay docenas de maneras de generar este:

  • uso de bucle y string.Format() o StringBuilder.
  • contador de uso entero y quitar la terminación " 'si el valor> 0
  • no ponen'," en la primera ejecución
  • etc.

Código de ejemplo de lo que tengo derecho ahora:

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

¿Cuál es el mejor código que es altamente reutilizable para el escenario anterior, y por qué?

Respuesta

4

string.join es la respuesta correcta, pero en el caso de un IEnumerable, LINQ es a menudo más corto que un bucle for:

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

¡Buen uso de LINQ! –

26

Desea utilizar el método string.Join, que existe en el BCL para este fin.

Ejemplo:

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

O si está utilizando .NET 3.5, se puede hacer esto con cualquier IEnumerable<string> como tal:

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

(Tenga en cuenta que esto no le da la mejor el rendimiento que requiere, aunque claramente sigue siendo "O (n)", y debería ser adecuado para casi todos los casos).

Ahora, si su enumerables no es del tipo string (genéricamente un IEnumerable<T>), sólo puede utilizar el método Select para convertir el resultado en una cadena, por ejemplo,

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

No estoy seguro de si está tratando con valores que puede contener potencialmente comas en sí mismos, pero esto se puede evitar si los encierra entre comillas (") y escapar de las comillas, de manera similar al formato CSV.

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

Por supuesto, dividirlos de nuevo es una tarea ligeramente tricónica, que requiere un poco de expresiones regulares.

+1

Hmm ... No sabía que esta función existe (hace que mi pregunta se vea mal). –

+0

@Adrian: sin preocupaciones. Si no eres de un fondo .NET, descubrir nuevas cosas en el marco no siempre es sencillo: es un proceso continuo para aumentar la familiaridad. – Noldorin

+1

Ese es el problema, he estado haciendo .NET desde la primera versión. Duh. –

2

Uso

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

Si tiene una matriz de cadenas, ir con solución Noldorin 's.

Pero si se trata de algún otro tipo de colección, que podría hacer esto:

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

Como han dicho otros: String.Join es normalmente la mejor manera de hacer esto. Pero, ¿y si acaba de tener un IEnumerable en lugar de una matriz? Tal vez tenga un código para enumerar estos al leerlos de un archivo con ejecución diferida. En este caso, String.Join no es tan agradable, porque tiene que recorrer las cadenas dos veces — una vez para crear la matriz y una para unirse a ella. En ese caso, usted quiere algo más parecido a esto:

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(); 
} 

Esto realizará casi, así como string.join, y trabaja en el caso más general. Entonces, dada una matriz de cadenas o cualquier otro IEnumerable se le puede llamar así:

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

Sí, ese es aparentemente el escenario más común. IEnumerable que cadena []. –

+0

+1 El 'result.Append (d) .Append (s)' es interesante ... nunca pensé en eso. Sería genial ver cuántas maneras diferentes se está haciendo esta simple tarea. –

+0

Lo realmente genial es que el jitter normalmente optimizará las asignaciones adicionales, por lo que el código hace _exactamente_ lo que usted desea o. –

Cuestiones relacionadas