I would like to know If It\'s possible to create a \"one-line\" Linq to retrieve longest string value of specific Datatable column, meaning that all column data (numbers, dates,
You are looking for ArgMax
- a value such that it has max value of some kind of property. Standard Linq doesn't provide ArgMax
but you can implement it via Aggregate
(i.e. get a single value from a sequence):
string maxString = dt
.AsEnumerable()
.Select(row => row[mycolumn].ToString())
.Aggregate((s, a) => a.Length > s.Length ? a : s);
First of all do not use AsEnumerable
right after dt.
.
Write somehow like this:
dt.OrderByDescending(row => row[mycolumn].Length).First();
You are almost there:
string maxString = dt.AsEnumerable()
.Select(row => row[mycolumn].ToString())
.OrderByDescending(st => st.Length).FirstOrDefault();
A Where
expects a predicate (function that will return true or false). Instead just order the projection (the .Select
) as you did and retrieve the first item.
Notice that is is an O(nlogn)
solution which can be improved to an O(n)
solution by not sorting but by finding the item with the max length. One possible way of doing so is an in Dimitry's answer. For less than huge collections I'm not sure one would really feel the difference but it is indeed worth noticing this.
See that you can also use MoreLinq's .MaxBy that can be added through Nuget (For the GitHub repo) which will both give you the O(n)
performance and the desired "one-liner":
var row = dt.AsEnumerable().MaxBy(r => r[mycolumn].ToString().Length);