Having issues with the OrderBy clause not having any impact on the sort. I have walked through this in the debugger and insuring this is a case that the sort line of the cod
OrderBy
doesn't sort a List<T>
or any other IEnumerable<T>
. It produces a new, sorted IEnumerable<T>
. So calling ddlOptions.OrderBy(...)
doesn't modify ddlOptions
.
If you have a List<T>
and wish to sort it, you can use the Sort method - in particular the overload that takes a Comparison<T>
as a parameter. This actually sorts the list instead of returning a new IEnumerable
.
Comparison<T> is a delegate representing a function that takes two of T
and returns a negative number if the first is "less" than the second, a positive number if the first is "greater" than the second, and zero if one isn't sorted before or after the other.
In this case you don't have to remember that. Instead, you can just do this:
ddlOptions.Sort((x, y) => string.CompareOrdinal(x.DisplayText, y.DisplayText));
You're passing in a function that takes two items in the list and returns the comparison result of their DisplayText
properties, which will be negative, 0, or positive.
Sometimes we use OrderBy
because it doesn't modify the original list. But if modifying the list is what we want then we can use Sort
.
Try:
if (sort)
{
ddlOptions = ddlOptions.OrderBy(l => l.DisplayText); <===== Should work now.
}
OrderBy
returns a query that would perform the ordering: it does not modify the original list (whereas something like List<T>.Sort
would modify the original)
Instead try something like:
ddlOptions = ddlOptions.OrderBy(l => l.DisplayText).ToList();
EDIT: You might want to play around with the type of ddlOptions
or where/how you return the data as we're doing an extra ToList
than probably necessary, but that's probably a minor/non-issue for this case anyway.
As others have said, you need to assign the result of OrderBy
to something as it doesn't mutate the sequence it acts on. It's easiest to make ddlOptions
an IEnumerable
instead of a List
, so that you can assign the result to that. The ToList
call on the select is also not needed:
public static IEnumerable<DDLOptions<TValueType>> GetDDLOptionsViewModel<TClass, TValueType>(
IEnumerable<TClass> list,
Func<TClass, TValueType> value,
Func<TClass, string> displayText,
bool sort = true
)
{
IEnumerable<DDLOptions<TValueType>> ddlOptions;
ddlOptions = list.Select(
l => new DDLOptions<TValueType>
{
Value = value(l),
DisplayText = displayText(l)
}
);
if (sort)
{
ddlOptions = ddlOptions.OrderBy(l => l.DisplayText);
}
return ddlOptions;
}
Note that this version of the method will use deferred execution, and so won't actually perform the Select/OrderBy until the sequence is iterated. If you don't want to do that, you can add ToList
on the return
line.
You need to type:
ddlOptions = ddlOptions.OrderBy(l => l.DisplayText);