Damar
Damar

Reputation: 27

Advance LINQ Ordering in Xamarin Forms

I have an ObservableCollection<myListType> Items. Each item in Items has a Project Name which can be "Administrative" and "Non-Administrative"(can be anything). I want to sort my Items using LINQ so that the items with Non-Administrative Project Name will be put on top of Administrative item.

So far i use,

Items.OrderBy(x => x.ProjectName != "Administrative").ThenBy(x => x.ProjectName == "Administrative");

But it doesn't sort the way i want and when i debug, I saw

"The Expression not supported".

Any ideas?

Upvotes: 1

Views: 201

Answers (3)

Nguyễn Văn Phong
Nguyễn Văn Phong

Reputation: 14228

Demo on dotnet fiddle

You make sure ProjectName == "Administrative" is always on the bottom.

var result = Items.OrderBy(p => p.ProjectName  == "Administrative");

Upvotes: 0

Paul Kertscher
Paul Kertscher

Reputation: 9732

How you use OrderBy and ThenBy shows a lock of understanding how OrderBy works. Please see the following example

| ID | Project Name   |
-----------------------
| 1  | Administrative |
| 2  | X              |
| 3  | Administrative |
| 4  | X              |

With the expression x.ProjectName != "Administrative", OrderBy will look at all items and sort them by whether ProjectName is not "Administrative".

| ID | Project Name   | ProjectName != "Administrative" |
---------------------------------------------------------
| 1  | Administrative | false                           |
| 2  | X              | true                            |
| 3  | Administrative | false                           |
| 4  | X              | true                            |

This will yield the following order

| ID | Project Name   | ProjectName != "Administrative" |
---------------------------------------------------------
| 1  | Administrative | false                           |
| 3  | Administrative | false                           |
| 2  | X              | true                            |
| 4  | X              | true                            |

because true is deemed greater by OrderBy. ThenBy now tries to order the groups internally, i.e. all items that matched a single "order key" are tried to be ordered by another criteria. See the following table for visualization

| ID | Project Name   | ProjectName != "Administrative" |
---------------------------------------------------------
| 1  | Administrative | false                           | Items for false
| 3  | Administrative | false                           |
=========================================================
| 2  | X              | true                            | Items for true
| 4  | X              | true                            |

Since ProjectName == "Administrative" has the same value for all items withing a single group, no subsequent ordering happens.

How can you achieved the desired outcome?

Simply use

Items.OrderBy(x => x.ProjectName == "Administrative")

Since ProjectName == "Administrative" is true for all administrative projects and true is deemed greater by OrderBy they show up last.

Upvotes: 1

javachipper
javachipper

Reputation: 537

According to your requirements, "Non-Administrative" should be put on top of "Administrative". You can do this:

var list = Items.OrderByDescending(x => x.ProjectName);

it will put "Non-Administrative" before "Administrative".

Edited

[for non-administrative name that has 'AAA']:

var result = Items.OrderBy(p => p.ProjectName  == "Administrative").ThenBy(p => p.ProjectName);

Upvotes: 1

Related Questions