Frederick Marcoux
Frederick Marcoux

Reputation: 2223

List Reordering for queue processing

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

Answers (2)

carndacier
carndacier

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 ?)

Edit

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

Saransh Kataria
Saransh Kataria

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

Related Questions