Reputation: 2223
While working on my project I've encountered a little glitch in the way that List works.
I have this list for example:
# Username - Status - Order - Timestamp
Admin, Available (int 0), 2, 10:45
User1, Not available (int 2), 1, 10:44
User2, Available, 3, 10:52
User3, Busy (int 1), 4, 10:33
I want a way to order it by multiple properties using something like a comparer.
I would like it to order by Status, so Available comes first, then by Timestamp to know who was first in the list.
So it would output:
Admin, 0, 0, 10:45
User2, 0, 1, 10:52
User3, 1, 2, 10:33
User1, 2, -1, 10:44
The User1 order must become -1 because it is not available so I want it to show last in my list, as busy users comes just before.
I need to keep an order because I want to know who's next. I tried to iterate the old list with ordering it then creating a new one with the good order but it doesn't work.
Here's the method I use:
public static List<ListMember> ReOrder(this List<ListMember> list)
{
int Index = 0;
List<ListMember> newList = new List<ListMember>();
foreach (ListMember member in list.OrderBy(x => x.ListOrder).ThenBy(x => x.DateEntered))
{
if (member.DateExited == null)
{
member.ListOrder = Index;
Index++;
}
else
{
member.ListOrder = -1;
}
newList.Add(member);
}
return newList;
}
This is needed because when someone pass from status 1 to 0, he become available but I don't want him to go first, I want him to go last in the list, then reindex the list.
Does someone have an idea on how a list can be greatly ordered.
Upvotes: 0
Views: 169
Reputation: 960
The Sinatr's comment should work.
As far as you need only available items, you can also do :
myList.Where(x => x.Status == 0).OrderBy(y => y.Timestamp)
I'm guessing to do the "Where" first will return a shorter list, then the orderBy would be faster to execute (someone to confirm ?)
After your edit, I would suggest to do like that :
public static List<ListMember> ReOrder(this List<ListMember> list)
{
int Index = 0;
foreach (ListMember member in list.OrderBy(x => x.DateEntered))
{
if (member.DateExited == null)
{
member.ListOrder = Index;
Index++;
}
else
{
member.ListOrder = -1;
}
}
return list;
}
I think you don't need to create a new list just to update a field. just update it directly in your list.
I would also suggest you to don't call often this function, because if you get a lot of items in your list, it can take time !
You should create a function in your ListMember
Class, "SetDateExit". It could be :
public void SetDateExit(DateTime dateExit)
{
this.DateExited = dateExit;
this.ListOrder = -1;
}
And then, when you need to display your result, just do like that :
return myList.Where(x => ListOrder != -1).OrderBy(x => x.ListOrder);
Upvotes: 2
Reputation: 1497
You can use dynamic LINQ for ordering by multiple fields. Using Linq.Dynamic, and the NuGet (https://www.nuget.org/packages/System.Linq.Dynamic.Library/) you can use comma separated values to order
myList.OrderBy("Availibility,Timestamp");
Upvotes: 0