Concat All Strings Inside a List<String> Using Linq

Concat all strings inside a List string using LINQ

Warning - Serious Performance Issues

Though this answer does produce the desired result, it suffers from poor performance compared to other answers here. Be very careful about deciding to use it


By using LINQ, this should work;

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

class description:

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

}
}

And here is my best :)

items.Select(i => i.Boo).Aggregate((i, j) => i + delimiter + j)

Concat all strings inside a List List string using LINQ

Since the linked question is tagged as c# so i add this answer with c# code.

If the number of nested lists are known You have to use SelectMany() over and over to unwrap all the nested lists to sequence of chars. then make string out of that sequence.

List<List<List<string>>> nestedList = new List<List<List<string>>>();
var result = new string(nestedList.SelectMany(x => x).SelectMany(x => x).SelectMany(x => x).ToArray());

If the number of nested lists are not known you have to use reflection, since the type is not known. I didnt used reflection directly but actually dynamic type does. The performance would be terrible here of course ;) but it does what you want.

using Microsoft.CSharp.RuntimeBinder;

//...

private static string ConcatAll<T>(T nestedList) where T : IList
{
dynamic templist = nestedList;
try
{
while (true)
{
List<dynamic> inner = new List<dynamic>(templist).SelectMany<dynamic, dynamic>(x => x).ToList();
templist = inner;
}
}
catch (RuntimeBinderException)
{
List<object> l = templist;
return l.Aggregate("", (a, b) => a + b);
}
}

Here is the test

private static void Main(string[] args)
{
List<List<List<string>>> nestedList = new List<List<List<string>>>
{
new List<List<string>> {new List<string> {"Hello "}, new List<string> {"World "}},
new List<List<string>> {new List<string> {"Goodbye "}, new List<string> {"World ", "End "}}
};

Console.WriteLine(ConcatAll(nestedList));
}

Outputs:

Hello World Goodbye World End

Update:

After a bit fiddling i ended up this implementation. maybe better without try catch.

private static string ConcatAll<T>(T nestedList) where T : IList
{
dynamic templist = nestedList;
while (templist.Count > 0 && !(templist[0] is char?))
{
List<dynamic> inner = new List<dynamic>(templist).SelectMany<dynamic, dynamic>(x =>
{
var s = x as string;
if (s != null)
{
return s.Cast<dynamic>();
}
return x;
}).ToList();
templist = inner;
}
return new string(((List<object>) templist).Cast<char>().ToArray());
}

Using Linq to concatenate a list of property of classes

This will do job for you:

var res = yourList.Select(x => x.Name).Aggregate((current, next) => current + ", " + next);

But, I recommend you to use String.Join(string separator, IEnumerable<string> values):

var res = String.Join(", ", yourList.Select(x => x.Name));

Additional details:

To tell the truth in such situations you can use either Aggregate or String.Join(). If we test the execution times of both queries, we will see that the second is faster than the first one. But the reason is not the Aggregate() function; the problem is that we are concatenating strings in a loop. This will generate lots of intermediate strings, resulting in bad performance. You can use StringBuilder.Append, if you want still to use Aggregate and increase the performance:

 var res = yourList.Select(x => x.Name)
.Aggregate(new StringBuilder(), (current, next) => current.Append(next).Append(", ")).ToString();

String.Join() uses a StringBuilder internally already and for that reason it will be the best choice.

Concatenate a constant string to each item in a List string using LINQ

List<string> yourList = new List<string>() { "X1", "Y1", "X2", "Y2" };
yourList = yourList.Select(r => string.Concat(r, 'y')).ToList();

Using LINQ to concatenate strings

This answer shows usage of LINQ (Aggregate) as requested in the question and is not intended for everyday use. Because this does not use a StringBuilder it will have horrible performance for very long sequences. For regular code use String.Join as shown in the other answer

Use aggregate queries like this:

string[] words = { "one", "two", "three" };
var res = words.Aggregate(
"", // start with empty string to handle empty list case.
(current, next) => current + ", " + next);
Console.WriteLine(res);

This outputs:

, one, two, three

An aggregate is a function that takes a collection of values and returns a scalar value. Examples from T-SQL include min, max, and sum. Both VB and C# have support for aggregates. Both VB and C# support aggregates as extension methods. Using the dot-notation, one simply calls a method on an IEnumerable object.

Remember that aggregate queries are executed immediately.

More information - MSDN: Aggregate Queries


If you really want to use Aggregate use variant using StringBuilder proposed in comment by CodeMonkeyKing which would be about the same code as regular String.Join including good performance for large number of objects:

 var res = words.Aggregate(
new StringBuilder(),
(current, next) => current.Append(current.Length == 0? "" : ", ").Append(next))
.ToString();

How to group in linq list and concatenate some string in c# linq

You can achieve the requirement as follows:

var resultSet = 
results.GroupBy(e => e.BelongCategoryName)
.ToDictionary(e => e.Key,
g => string.Join(",", g.Select(a => a.ItemName)));

resultSet is now a Dictionary<string, string>.

or if you want to chain the above query to the one you've already started:

var results = (from myobject in selectedItemList
where myobject.ItemType == 5
where myobject.BelongItemIndex == selectedItemList.IndexOf(C)
orderby myobject.BelongCategoryName
group myobject by myobject.BelongCategoryName)
.ToDictionary(e => e.Key,
g => string.Join(",", g.Select(a => a.ItemName)));

or using query syntax only:

var results = from myobject in selectedItemList
where myobject.ItemType == 5
where myobject.BelongItemIndex == selectedItemList.IndexOf(C)
orderby myobject.BelongCategoryName
group myobject by myobject.BelongCategoryName into h
select new
{
BelongCategoryName = h.Key,
ItemNames = string.Join(", ", from e in h select e.ItemName)
};

Concatenate All Properties to a String with LINQ

If it's OK to list fields manually:

String.Join(";", myObjs.Select(x => $"{x.Line},{x.Name1},{x.Name2}"))

If not, but all fields are non-collections, generics or indexers

var fields = typeof(MyClass).GetFields();
var result = String.Join(";", myObjs.Select(x =>
String.Join(",", fields.Select(f => f.GetValue(x)))
));

NOTE: If your class actually have properties instead of fields, you should use GetProperties() instead of GetFields().


And last option, if it's OK to override ToString() method of your class:

 public override string ToString() => $"{Line},{Name1},{Name2}";

And converting list of such objects will look like

 String.Join(";", myObjs)

Concat all strings from dictionary (values) using LINQ without external variable

You shouldn't use LINQ to concat strings. This can become very expenisve. Use string.Join() innstead:

string result = string.Join(Environment.NewLine, dict.Values);

However, this does not guarantee the correct order, because a Dictionary<> is not sorted. To sort the output by the Keys you can do this:

string sorted = string.Join(Environment.NewLine, 
dict.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value));

Is it possible to concat strings when grouping with Linq?

Simply use String.Join overload that accepts an IEnumerable<string>:

var size = String.Join("", groupedByColorCode.Select(bcc => bcc.Size));

Edit: Oh:I get it! I never ever use Linq for SQL queries, so I wasn't catching up with the problem. If this gets translated into SQL, there is no way you can do that on the database (if you're not on PostgreSQL or some other smart db and you don't want to mess with SQL itself). SQL can do Sum, Avg, etc, but no Concat (usually).
You'll have to retrieve the colorcodes and join them after the roundtrip on the db, with the provided method.

Concatenate strings inside a linq 'select new object {

You are currently concatenating a string with a char value while what you want is to concatenate strings. the string + operator is expeciting another string and not a char. use " " instead:

ReportedByName = ub.FirstName + " " + ub.LastName

Of course other ways way be:

  1. string.Format or C# 6.0 syntactic sugar for it of string
    interpolation

    ReportedByName = string.Format("{0} {1}", ub.FirstName, ub.LastName)
    ReportedByName = $"{ub.FirstName} {ub.LastName}" //syntactic sugar of option above
  2. string.join (which is what I'll go for if you have more values)

    ReportedByName = string.Join(" ", ub.FirstName, ub.LastName)
  3. string.Concat

    ReportedByName = string.Concat(ub.FirstName, " ", ub.LastName)

Because you are in a linq to entities and not objects in memory the string.Join (and thus also string interpolation) and string.Format might not work if you are in a linq that is translated to an sql query. If you want to use those options first retrieve the items to memory (using ToList()/AsEnumerable() and then use them to concatenate the strings. See Jon's answer



Related Topics



Leave a reply



Submit