Конкатить все строки внутри списка <string> с помощью LINQ

543

Есть ли какое-нибудь простое выражение LINQ для объединения всех List<string>элементов моей коллекции в один stringс символом-разделителем?

Что делать, если коллекция состоит из пользовательских объектов вместо string? Представь, что мне нужно объединиться object.Name.

Джоби Джой
источник
37
Почему linq, а не string.Join ()?
Алан
14
string.Join лучше, но я думаю, что linq делает ваш код забавным, вот почему!
Али Эрсез
14
String.Join лучше, потому что он использует StringBuilder и избегает наследственной производительности O (n ^ 2) повторной конкатенации.
Кеннет Беленький
1
проблемы с производительностью при использовании LINQ?
PreguntonCojoneroCabrón

Ответы:

525

Используя LINQ, это должно работать;

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

описание класса:

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

Применение:

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

    }
}

И вот мой лучший :)

items.Select(i => i.Boo).Aggregate((i, j) => i + delimiter + j)
Али Эрсез
источник
40
O (n ^ 2) время бьет снова.
Кеннет Беленький
2
Если вы не видите метод Aggregate, вам нужно добавить его с помощью System.Linq;
Седрик Гиймет
6
Проблема в том, что выше метод LinQ не работает с пустым или одноэлементным списком.
Александр
2
это вызовет InvalidOperationException, если элементы пустые.
2xMax
10
почему бы просто не использовать string.join? Пожалуйста, примите ответ Sedat, чтобы любой спешащий не выбрал это решение, когда Sedat - лучший выбор.
Skychan
966

В .NET 4.0 или более поздних версиях:

String.Join(delimiter, list);

достаточно.

Седат Капаноглу
источник
91
Я все для решений LINQ, но это более эффективно, чем LINQ и метод Aggregate ().
andleer
17
намного чище! отлично работал для меня! string.Join (",", accs.Select (x => x.AccountID) .ToArray ()),
m4tt1mus
32
@KonstantinSalavatov Я опубликовал свой ответ до того, как ОП пояснил, что он должен быть в LINQ. Это все еще совершенно верно для любого, кто сталкивается с этим ответом, ища "не обязательно-LINQ" решение в Google. Относительно этого ответа «бесполезно» в этом контексте несправедливо.
Седат Капаноглу
7
Это также может быть использовано для других вещей, кроме List <String>s, и вызовет метод ToString ().
Киан
не работает, если это запрос к базе данных. Это работает только на память.
alansiqueira27
124

Это для строкового массива:

string.Join(delimiter, array);

Это для списка <string>:

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

И это для списка пользовательских объектов:

string.Join(delimiter, list.Select(i => i.Boo).ToArray());
Александр Прокофьев
источник
25
String.Join имеет перегрузку, которая принимает IEnumerable, поэтому вам не нужен вызов ToArray ()
arolson101
9
Имейте в виду, перегрузка IEnumerable существует только в версии 4.0 или более поздней. Если вы используете более старую версию, вам все равно понадобится ToArray ().
Rakuen42
2
Ах! Эта последняя перегрузка была той, которую я искал. Я знал, что должен быть способ извлечь определенную собственность. :)
Майк Девенни
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
источник
26

Хороший вопрос. Я использую

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

Это не LINQ, но это работает.

Джейкоб Проффитт
источник
Зачем вам нужно вызывать .ToArray ()?
Ε Г И І И О
Потому что в плохие времена 2009 года у string.Join не было расширения, которое принимало бы IEnumerable.
Джейкоб Проффитт
8
List<string> strings = new List<string>() { "ABC", "DEF", "GHI" };
string s = strings.Aggregate((a, b) => a + ',' + b);
Питер МакГ
источник
7

Я думаю, что если вы определите логику в методе расширения, код будет намного более читабельным:

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
источник
6

Вы можете просто использовать:

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

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

Удачного кодирования!

Нишант Шаан
источник
3

Я сделал это с помощью LINQ:

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

string joinedString = string.Join(",", oCSP.Select(p => p.ProductName));
Biddut
источник