Połącz wszystkie ciągi wewnątrz listy <ciąg> za pomocą LINQ

542

Czy istnieje jakieś proste wyrażenie LINQ, które pozwala połączyć wszystkie moje List<string>elementy kolekcji w jeden stringze znakiem separatora?

Co jeśli kolekcja zawiera niestandardowe obiekty zamiast string? Wyobraź sobie, że muszę się połączyć object.Name.

Jobi Joy
źródło
37
Dlaczego linq a nie string.Join ()?
Alan
14
string.Join jest lepszy, ale myślę, że linq sprawia, że ​​Twój kod jest fajny, może to być powód!
Ali Ersöz,
14
String.Join jest lepszy, ponieważ używa StringBuilder i unika dziedziczonej wydajności O (n ^ 2) powtarzającej się konkatenacji.
Kennet Belenky
1
problemy z wydajnością przy użyciu LINQ?
PreguntonCojoneroCabrón 27.04.17

Odpowiedzi:

524

Przy użyciu LINQ powinno to działać;

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

opis klasy:

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

Stosowanie:

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

    }
}

A oto moje najlepsze :)

items.Select(i => i.Boo).Aggregate((i, j) => i + delimiter + j)
Ali Ersöz
źródło
40
Czas O (n ^ 2) uderza ponownie.
Kennet Belenky
2
Jeśli nie widzisz metody Aggregate, musisz dodać za pomocą System.Linq;
Cédric Guillemette,
6
Problem polega na tym, że powyższa metoda LinQ nie działa z pustą lub pojedynczą listą elementów.
Alexander
2
spowoduje zgłoszenie wyjątku InvalidOperationException w przypadku, gdy elementy są puste.
2xMax
10
dlaczego nie użyć po prostu string.join? Proszę przyjąć odpowiedź Sedata, aby nikt w pośpiechu nie wybrał tego rozwiązania, gdy Sedat jest lepszym wyborem.
Skychan
966

W .NET 4.0 lub nowszych wersjach:

String.Join(delimiter, list);

jest wystarczający.

Sedat Kapanoglu
źródło
91
Jestem zwolennikiem rozwiązań LINQ, ale jest to bardziej wydajne niż LINQ i metoda Aggregate ().
andleer
17
dużo czystsze! działało świetnie dla mnie! string.Join (",", accs.Select (x => x.AccountID) .ToArray ()),
m4tt1mus
32
@KonstantinSalavatov Wysłałem odpowiedź, zanim OP wyjaśniła, że ​​musi ona być w LINQ. Jest to nadal w pełni poprawne dla każdego, kto wpadnie na tę odpowiedź, szukając rozwiązania „niekoniecznie LINQ” w Google. Jeśli chodzi o tę odpowiedź, „nieprzydatne” w tym kontekście jest niesprawiedliwe.
Sedat Kapanoglu
7
Można to również wykorzystać do rzeczy innych niż List <String>s i wywoła metodę ToString ().
Kian
nie działa, jeśli jest to zapytanie prowadzące do bazy danych. Działa tylko na pamięć.
alansiqueira27
124

To jest dla tablicy ciągów:

string.Join(delimiter, array);

To jest dla listy <ciąg>:

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

A to dotyczy listy niestandardowych obiektów:

string.Join(delimiter, list.Select(i => i.Boo).ToArray());
Alexander Prokofyev
źródło
25
String.Join ma przeciążenie, które wymaga IEnumerable, więc nie potrzebujesz wywołania ToArray ()
arolson101 14.11.11
9
Należy pamiętać, że przeciążenie IEnumer istnieje tylko w wersji 4.0 lub nowszej. Jeśli używasz starszej wersji, nadal będziesz potrzebować ToArray ().
Rakuen42
2
Ach! To ostatnie przeciążenie było tym, którego szukałem. Wiedziałem, że musi istnieć sposób na wydobycie konkretnej nieruchomości. :)
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
źródło
26

Dobre pytanie. Używałem

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

To nie jest LINQ, ale działa.

Jacob Proffitt
źródło
Dlaczego musisz wywoływać .ToArray ()?
Г Г И І И О
Ponieważ w czasach złych ole w 2009 roku string.Join nie miał rozszerzenia, które akceptowało IEnumerable.
Jacob Proffitt
8
List<string> strings = new List<string>() { "ABC", "DEF", "GHI" };
string s = strings.Aggregate((a, b) => a + ',' + b);
Peter McG
źródło
7

Myślę, że jeśli zdefiniujesz logikę w metodzie rozszerzenia, kod będzie znacznie bardziej czytelny:

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
źródło
6

Możesz po prostu użyć:

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

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

Miłego kodowania!

Nishanth Shaan
źródło
3

Zrobiłem to za pomocą LINQ:

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

string joinedString = string.Join(",", oCSP.Select(p => p.ProductName));
Biddut
źródło