Concattez toutes les chaînes d'une List <string> à l'aide de LINQ

543

Existe-t-il une expression LINQ simple pour concaténer tous mes List<string>éléments de collection en un seul stringavec un caractère délimiteur?

Et si la collection est constituée d'objets personnalisés au lieu de string? Imaginez que je dois concaténer object.Name.

Jobi Joy
la source
37
Pourquoi linq et non string.Join ()?
Alan
14
string.Join est mieux mais je pense que linq rend votre code amusant, c'est peut-être la raison!
Ali Ersöz
14
String.Join est meilleur car il utilise un StringBuilder et évite les performances inhérentes O (n ^ 2) de la concaténation répétée.
Kennet Belenky
1
des problèmes de performances avec LINQ?
PreguntonCojoneroCabrón

Réponses:

525

En utilisant LINQ, cela devrait fonctionner;

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

description de la classe:

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

Usage:

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

    }
}

Et voici mon meilleur :)

items.Select(i => i.Boo).Aggregate((i, j) => i + delimiter + j)
Ali Ersöz
la source
40
O (n ^ 2) le temps frappe à nouveau.
Kennet Belenky
2
Si vous ne voyez pas la méthode Aggregate, vous devez ajouter à l'aide de System.Linq;
Cédric Guillemette
6
Le problème est que la méthode LinQ ci-dessus ne fonctionne pas avec une liste vide ou à un seul élément.
Alexander
2
il lèvera une InvalidOperationException au cas où les éléments seraient vides.
2xMax
10
pourquoi ne pas simplement utiliser string.join? Veuillez accepter la réponse de Sedat afin que toute personne pressée ne choisisse pas cette solution lorsque Sedat est le meilleur choix.
Skychan
966

Dans .NET 4.0 ou versions ultérieures:

String.Join(delimiter, list);

est suffisant.

Sedat Kapanoglu
la source
91
Je suis pour les solutions LINQ mais c'est plus efficace que LINQ et la méthode Aggregate ().
andleer
17
beaucoup plus propre! a très bien fonctionné pour moi! string.Join (",", accs.Select (x => x.AccountID) .ToArray ()),
m4tt1mus
32
@KonstantinSalavatov J'avais posté ma réponse avant qu'OP n'ait précisé qu'elle devait être dans LINQ. Elle est toujours parfaitement valable pour quiconque se heurte à cette réponse tout en recherchant une solution "pas nécessairement LINQ" sur Google. Il est injuste de considérer cette réponse "non utile" dans ce contexte.
Sedat Kapanoglu
7
Cela peut également être utilisé pour des choses autres que List <String>et appellera la méthode ToString ().
Kian
ne fonctionne pas s'il s'agit d'une requête allant dans la base de données. Cela ne fonctionne que sur la mémoire.
alansiqueira27
124

C'est pour un tableau de chaînes:

string.Join(delimiter, array);

C'est pour une liste <chaîne>:

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

Et ceci est pour une liste d'objets personnalisés:

string.Join(delimiter, list.Select(i => i.Boo).ToArray());
Alexander Prokofyev
la source
25
String.Join a une surcharge qui prend un IEnumerable, vous n'avez donc pas besoin de l'appel ToArray ()
arolson101
9
Gardez à l'esprit que la surcharge IEnumerable n'existe que dans la version 4.0 ou ultérieure. Si vous utilisez une ancienne version, vous aurez toujours besoin de ToArray ().
Rakuen42
2
Ah! Cette dernière surcharge était celle que je cherchais. Je savais qu'il devait y avoir un moyen d'extraire une propriété spécifique. :)
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
la source
26

Bonne question. J'utilise

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

Ce n'est pas LINQ, mais cela fonctionne.

Jacob Proffitt
la source
Pourquoi devez-vous appeler .ToArray ()?
Ε Г И І И О
Parce que dans les mauvais jours de 2009, string.Join n'avait pas d'extension qui acceptait un IEnumerable.
Jacob Proffitt
8
List<string> strings = new List<string>() { "ABC", "DEF", "GHI" };
string s = strings.Aggregate((a, b) => a + ',' + b);
Peter McG
la source
7

Je pense que si vous définissez la logique dans une méthode d'extension, le code sera beaucoup plus lisible:

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
la source
6

Vous pouvez simplement utiliser:

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

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

Bon codage!

Nishanth Shaan
la source
3

Je l'ai fait en utilisant LINQ:

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

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