Conversión de una lista <int> en una cadena separada por comas


116

¿Hay alguna forma de tomar una lista y convertirla en una cadena separada por comas?

Sé que puedo hacer un bucle y construirlo, pero de alguna manera creo que algunos de ustedes son una forma más genial de hacerlo.

Realmente quiero aprender este tipo de 'trucos', así que explique o enlace a los documentos sobre el método que usa.

Respuestas:


189
List<int> list = ...;
string.Join(",", list.Select(n => n.ToString()).ToArray())

7
Inteligente pero lento e hinchado, ya que asigna una cadena por elemento. Usar un StringBuilder sería mucho más eficiente.
Steven Sudit

3
Por lo que vi en línea (búsqueda rápida) String.Join es más rápido que usar un StringBuilder.
Yuriy Faktorovich


6
Creo que Steven se refiere a la parte n.ToString () en lugar de a String.Join.
Larsenal

9
Larsenal: pero StringBuilder.Append (Int32) llama internamente a ToString en el entero de todos modos. StringBuilder no evita mágicamente el costo de asignar una cadena para cada elemento; simplemente lo esconde muy bien fuera de la vista.
itowlson

115

La solución simple es

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

Lo usé hace un momento en mi código, funcionando en funtastic.


1
¡Gracias! este es un enfoque hermoso
Irfan Ashraf

2
Este es un enfoque mejor que el de respuesta aceptada. Con este enfoque, no tiene que importar Linq y esto es más rápido.
JoKeRxbLaCk

¡Frio! Nunca supe la cadena. Join tiene sobrecargas genéricas. Gracias.
mrmashal

10
List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(String.Join(",", list.Select(i => i.ToString()).ToArray()));

Genial si no puede usar .NET 4
Greg Woods

6

Para obtener aproximadamente un millón de soluciones a una versión un poco más complicada de este problema, muchas de las cuales son lentas, con errores o ni siquiera se compilan, consulte los comentarios de mi artículo sobre este tema:

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

y el comentario de StackOverflow:

El desafío de Eric Lippert "sutilezas por comas", ¿la mejor respuesta?


Gracias por el enlace. ¡Este problema de concatenación de cadenas ha resultado ser más complejo y más educativo de lo que esperaba!
Steven Sudit

4

Para mayor frescura, haría de este un método de extensión en IEnumerable <T> para que funcione en cualquier IEnumerable:

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

Úselo de la siguiente manera:

List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(list.BuildString(", "));

Dos posibles optimizaciones: 1) Agregue el delimitador después de cada elemento independientemente, luego elimine el adicional después de que finalice el ciclo. 2) Especifique una capacidad para StringBuilder.
Steven Sudit

1
Si extrae Reflector, resulta que Join suma las longitudes para calcular previamente el tamaño del búfer, y también "ceba la bomba" agregando la primera cadena fuera del bucle, y luego, dentro del bucle, agregando incondicionalmente el delimitador antes del siguiente cadena. Combinado con algunos trucos internos / inseguros, debería ser muy rápido.
Steven Sudit

@Steven: siguió tu consejo.
cdiggins

1
Codifica de forma rígida el delimitador en su extensión e ignora el valor pasado para un delimitador, y omitió el punto y coma. Debería serreturn string.Join(delim, self);
Andrew

1

Parece razonablemente rápido.

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

1

Mi entrada "inteligente":

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

Simplemente no he descubierto cómo agregar condicionalmente la coma.


1
No escriba Selectcon efectos secundarios en la lambda. En este caso, ni siquiera está utilizando y, por lo que su Selectes esencialmente un foreach- así que escríbalo como tal.
Pavel Minaev

No estaba sugiriendo esto como una buena solución. OP quería algo más interesante que foreach.
Larsenal

Sí, pero abusar de Selectcomo foreachva más allá de "interesante" y en, bueno, "abuso". Un enfoque más interesante aquí sería usar Enumerable.Aggregatecon StringBuildercomo valor inicial; inténtelo.
Pavel Minaev

Buena idea. Tengo que salir, pero puedo darle una vuelta.
Larsenal

0

puede utilizar, la biblioteca System.Linq; Es más eficiente:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.