Concat todas las cadenas dentro de una Lista <cadena> usando LINQ

543

¿Hay alguna expresión LINQ fácil para concatenar todos List<string>los elementos de mi colección a un solo stringcon un carácter delimitador?

¿Qué pasa si la colección es de objetos personalizados en lugar de string? Imagina que necesito concatenar object.Name.

Jobi Joy
fuente
37
¿Por qué linq y no string.Join ()?
Alan
14
string.Join es mejor, pero creo que linq hace que su código sea divertido, ¡ese podría ser el motivo!
Ali Ersöz
14
String.Join es mejor porque utiliza un StringBuilder y evita el rendimiento O (n ^ 2) heredado de la concatenación repetida.
Kennet Belenky
1
problemas de rendimiento con LINQ?
PreguntonCojoneroCabrón

Respuestas:

525

Al usar LINQ, esto debería funcionar;

string delimiter = ",";
List<string> items = new List<string>() { "foo", "boo", "john", "doe" };
Console.WriteLine(items.Aggregate((i, j) => i + delimiter + j));

descripción de clase:

public class Foo
{
    public string Boo { get; set; }
}

Uso:

class Program
{
    static void Main(string[] args)
    {
        string delimiter = ",";
        List<Foo> items = new List<Foo>() { new Foo { Boo = "ABC" }, new Foo { Boo = "DEF" },
            new Foo { Boo = "GHI" }, new Foo { Boo = "JKL" } };

        Console.WriteLine(items.Aggregate((i, j) => new Foo{Boo = (i.Boo + delimiter + j.Boo)}).Boo);
        Console.ReadKey();

    }
}

Y aquí está mi mejor :)

items.Select(i => i.Boo).Aggregate((i, j) => i + delimiter + j)
Ali Ersöz
fuente
40
O (n ^ 2) el tiempo ataca de nuevo.
Kennet Belenky
2
Si no puede ver el método Agregado, debe agregarlo usando System.Linq;
Cédric Guillemette
66
El problema es que el método anterior de LinQ no funciona con una lista vacía o de un solo elemento.
Alexander
2
arrojará una InvalidOperationException en caso de que los elementos estén vacíos.
2xMax
10
¿Por qué no usar string.join? Acepte la respuesta de Sedat para que cualquier persona apurada no elija esta solución cuando Sedat sea la mejor opción.
Skychan
966

En .NET 4.0 o versiones posteriores:

String.Join(delimiter, list);

es suficiente.

Sedat Kapanoglu
fuente
9191
Estoy totalmente a favor de las soluciones de LINQ, pero esto es más eficiente que LINQ y el método Aggregate ().
andleer
17
mucho más limpio! funcionó muy bien para mí! string.Join (",", accs.Select (x => x.AccountID) .ToArray ()),
m4tt1mus
32
@ KonstantinSalavatov Había publicado mi respuesta antes de que OP aclarara que tenía que estar en LINQ. Sigue siendo perfectamente válido para cualquiera que se encuentre con esta respuesta mientras busca una solución "no necesariamente LINQ" en Google. Respecto a esta respuesta "no útil" en ese contexto es injusto.
Sedat Kapanoglu
77
Esto también se puede usar para otras cosas que no sean List <String>s y llamará al método ToString ().
Kian
no funciona si se trata de una consulta que va a la base de datos. Solo funciona en la memoria.
alansiqueira27
124

Esto es para una matriz de cadenas:

string.Join(delimiter, array);

Esto es para una Lista <cadena>:

string.Join(delimiter, list.ToArray());

Y esto es para una lista de objetos personalizados:

string.Join(delimiter, list.Select(i => i.Boo).ToArray());
Alexander Prokofyev
fuente
25
String.Join tiene una sobrecarga que toma un IEnumerable, por lo que no necesita la llamada ToArray ()
arolson101
99
Tenga en cuenta que la sobrecarga IEnumerable solo existe en 4.0 o posterior. Si está utilizando una versión anterior, aún necesitará ToArray ().
Rakuen42
2
Ah! Esa última sobrecarga fue la que estaba buscando. Sabía que tenía que haber una manera de extraer una propiedad específica. :)
Mike Devenney
56
using System.Linq;

public class Person
{
  string FirstName { get; set; }
  string LastName { get; set; }
}

List<Person> persons = new List<Person>();

string listOfPersons = string.Join(",", persons.Select(p => p.FirstName));
dev.bv
fuente
26

Buena pregunta. He estado usando

List<string> myStrings = new List<string>{ "ours", "mine", "yours"};
string joinedString = string.Join(", ", myStrings.ToArray());

No es LINQ, pero funciona.

Jacob Proffitt
fuente
¿Por qué tienes que llamar a .ToArray ()?
Ε Г И І И О
Porque en los malos días de 2009, string.Join no tenía una extensión que aceptara un IEnumerable.
Jacob Proffitt
8
List<string> strings = new List<string>() { "ABC", "DEF", "GHI" };
string s = strings.Aggregate((a, b) => a + ',' + b);
Peter McG
fuente
7

Creo que si define la lógica en un método de extensión, el código será mucho más legible:

public static class EnumerableExtensions { 
  public static string Join<T>(this IEnumerable<T> self, string separator) {  
    return String.Join(separator, self.Select(e => e.ToString()).ToArray()); 
  } 
} 

public class Person {  
  public string FirstName { get; set; }  
  public string LastName { get; set; }  
  public override string ToString() {
    return string.Format("{0} {1}", FirstName, LastName);
  }
}  

// ...

List<Person> people = new List<Person>();
// ...
string fullNames = people.Join(", ");
string lastNames = people.Select(p => p.LastName).Join(", ");
Jordão
fuente
6

Simplemente puede usar:

List<string> items = new List<string>() { "foo", "boo", "john", "doe" };

Console.WriteLine(string.Join(",", items));

¡Feliz codificación!

Nishanth Shaan
fuente
3

He hecho esto usando LINQ:

var oCSP = (from P in db.Products select new { P.ProductName });

string joinedString = string.Join(",", oCSP.Select(p => p.ProductName));
Biddut
fuente