Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I sort the contents of a string list by length descending?

I want to sort a string list of phrases by length, descending, so that this:

Rory Gallagher
Rod D'Ath
Gerry McAvoy
Lou Martin

would end up as:

Rory Gallagher
Gerry McAvoy
Lou Martin
Rod D'Ath

I wanted to try this first:

List<string> slPhrasesFoundInBothDocs;
. . . // populate slPhrasesFoundInBothDocs
slPhrasesFoundInBothDocs = slPhrasesFoundInBothDocs.OrderByDescending(x => x.Length);

...but the last line wouldn't compile, and intellisense suggested that I change it to:

slPhrasesFoundInBothDocs = (List<string>)slPhrasesFoundInBothDocs.OrderByDescending(x => x.Length);

...which I did. It compiles, but throws a runtime exception, namely, "Unable to cast object of type 'System.Linq.OrderedEnumerable2[System.String,System.Int32]' to type 'System.Collections.Generic.List1[System.String]'."

Do I need a fix to this code, or to attack it in a completely different way?

like image 759
B. Clay Shannon-B. Crow Raven Avatar asked Nov 16 '25 02:11

B. Clay Shannon-B. Crow Raven


2 Answers

Use this:

slPhrasesFoundInBothDocs =
    slPhrasesFoundInBothDocs
        .OrderByDescending(x => x.Length)
        .ToList();
like image 51
see sharper Avatar answered Nov 18 '25 15:11

see sharper


The definition of the List<T> class is:

public class List<T> :  IEnumerable<T>,...

List<T> class inherits from IEnumerable<T>, with OrderByDescending returning an IOrderedEnumerable<out TElement>—which also inherits from IEnumerable<T>.

The definition of the IOrderedEnumerable interface is:

public interface IOrderedEnumerable<out TElement> : IEnumerable<TElement>, IEnumerable

Check this:

IEnumerable<string> enumerable1 = new List<string>{ "x","y"};
List<string> list1 = (List<string>)enumerable1; //valid

IEnumerable<string> enumerable2 =new  Collection<string>{ "x","y"};
List<string> list2 = (List<string>)enumerable2; //runtime error

It's always true that every List<T> or Collection<T> is an IEnumerable<T>. But it's not true to say that every IEnumerable<T> is a List<T>.

enter image description here

There wouldn't be a situation which IOrderedEnumerable<out TElement> could be cast to a List, because they are not in the same hierarchy.

So, as @cee sharper mentioned, we instead have to call the ToList() extension method, to convert IOrderedEnumerable<out TElement> to a List<T>:

List<string> list = new List{"x","xx","xxx"}.OrderByDescending(x => x.Length).ToList();
like image 39
Hassan Monjezi Avatar answered Nov 18 '25 16:11

Hassan Monjezi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!