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.