Reputation:
Below is my code , i am trying to get distinct sub keys in descending order
All is well but in OrderByDescending
it is not suggesting field
List<string> Sub_key_list = dt
.AsEnumerable()
.Select(d => d.Field<string>("Sub_Key_Name"))
.Distinct()
.OrderByDescending(e => e.not suggesting field here )
.ToList();
Am i writing it wrong ?
Upvotes: 0
Views: 117
Reputation: 25
First of all i doubt if it works d.Field("Sub_Key_Name") ?
I create a simple example of list of strings and then sorting :
var list = new List<string>();
list.Add("a");
list.Add("ab");
list.Add("ab");
list.Add("abc");
list.Add("lmn");
list.Add("xyz");
var q = list.AsEnumerable().Select(s => s).Distinct().OrderByDescending(s => s).ToList();
foreach(var i in q)
{
Console.WriteLine(i);
}
It works fine.
Upvotes: 0
Reputation: 70691
According to one comment:
OP is expecting the same intellisense behavior like two rows above where he select a field from a datatable - but at that point there is no more datatable, just string
That is, you want to be able to order by some field in your data row other than the one you are selecting for the Distinct()
operation. I think that gets a little complicated, but it's doable.
Unfortunately, the Distinct()
method returns an unordered sequence. I.e. you can't do your ordering first and then use Distinct()
. This prevents us from being able to extract into an anonymous type the fields we care about for ordering and the final value, ordering that data, and then using Distinct()
on the result.
On the other hand, without a custom equality comparer implementation, Distinct()
will apply its logic to the entire object, rather than just one field (there's not an overload that lets you select a value for the operation). So we would need to provide a custom equality comparer, which is still doable with anonymous types, but gets even more complicated.
There is also a logical issue: the Distinct()
operation necessarily will reduce several rows with the same value into just one. This results in there just being one ordering field value, from the potentially many that were there, but you don't get to pick which one.
Fortunately, all of the above can be addressed using GroupBy()
instead of Distinct()
. With GroupBy()
, you can initially select an anonymous type containing the fields of interest, then group them by a specific key (the "Sub_Key_Name" value in this case), but without losing any of the ordering fields. You can then pick from the ordering fields using whatever logic makes sense in your application (your question doesn't specify, so for this example, I just use the maximum value), and use that value to actually order the results. Finally, selecting just the grouping key gets you the final value you wanted.
That would look something like this:
List<string> Sub_key_list = dt
.AsEnumerable()
.Select(d => new
{
OrderKey = d.Field<int>("OrderKey"), // i.e. whatever you want here
Value = d.Field<string>("Value"),
})
.GroupBy(e => e.Value)
.OrderByDescending(e => e.Max(x => x.OrderKey)) // I used Max...use whatever you want
.Select(e => e.Key)
.ToList();
For additional inspiration, see also related/similar questions:
Linq orderby and distinct
Select Multiple Fields from List in Linq
Distinct in Linq based on only one field of the table
Upvotes: 0
Reputation: 157048
The argument passed to OrderByDescending
is an IEnumerable<string>
, so e
is your string
here. That means you can simply order by e
like this:
.OrderByDescending(e => e)
Upvotes: 3