Using Linq to Concatenate Strings

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

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

concatenate strings in LINQ query

you can use it:

FullName = user.UserName + " " + user.FirstName

But I think that it could be better solution (of cource if it's possible for you):

public class User
{
public int Id {get;set;}
public string UserName {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
public string FullName
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
}

then in your query build it:

var userList = users.Select(user => new User()
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName
}).ToList();

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.

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)

Concatenating two strings to one in LINQ query

With C# 6 string interpolation, it becomes:

var displayName = _db.Users.Where(e => e.Id == appId)
.Select(d => $"{d.Firstname} {d.Lastname}");

Please note: .Where will return an enumeration! You might consider .FirstOrDefault or just .First instead of the .Where.

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 string in Linq query

Convert the query result to a list first then use select to make the toString work.

var result = queryResult.OrderBy(c => c.TariffName)
.Take(count);
var list = result.ToList().Select(c => new
{
Text = c.TariffName + " - " + c.LineRental.ToString(),
Key = c.TariffId,
Price = c.LineRental
});

Using LINQ to Group, concatenate and Counting

You may replace the line

Country= string.Join(" - ", y.Select(z =>z.Country).Distinct())

With:

Country= string.Join(" - ", y.Select(z =>$"{z.Country}({y.Where(c=>c.Country==z.Country).Count()})").Distinct())

It's not the best solution, but it keeps your way of doing query.

If you want this query to be little bit more optimized, then you may introduce distinctCountries variable f.e.:

list.GroupBy(x => x.race)
.Select(y => {
var distinctCountries = y.Select(z => z.country).Distinct();
return new
{
Race = y.Key,
Count = y.Count(),
Country = string.Join(" - ", distinctCountries.Select(z => $"{z}({y.Where(c => c.country == z).Count()})").Distinct())

};

});


Related Topics



Leave a reply



Submit