sort a queue in C#
Asked Answered
G

3

5

Even though this question sounds as a duplicate, I searched a lot but couldn't find a proper solution.

I have following classes

public enum ChangeType
{ 
    Add,
    Modify,
    Delete
}



public enum ChangedObjectType
{ 
    Project,
    Customer,
    Border,
    Photo
}

public struct ChangeInfo
{
    public ChangeType typeofChange { get; private set; }
    public ChangedObjectType objectType { get; private set; }

    public string objectID { get; private set; }

    public ChangeInfo(ChangeType changeType, ChangedObjectType changeObj, string objectId):this()
    {
        typeofChange = changeType;
        objectType = changeObj;
        objectID = objectId;
    }

}

thread :

public class ChangeInfoUploader
{ 
    static Queue<ChangeInfo> changeInfoQueue = new Queue<ChangeInfo>();
    static Thread changeInfoUploaderThread = new Thread(new ThreadStart(ChangeInfoUploaderProc));
    static bool isStarted = false;
    static Project currentProject;

    public static void Initialize(Project curproject)
    {
        currentProject = curproject;
        isStarted = true;
        changeInfoUploaderThread.Start();
        ResumeData();
    }

    static void ChangeInfoUploaderProc()
    {
        while (isStarted)
        {
            if (currentProject != null)
            {
                ChangeInfo? addToDb = null;

             // I need to sort changeInfoQueue before dequeue
                lock (changeInfoQueue)
                {
                    if (changeInfoQueue.Count != 0)
                        addToDb = changeInfoQueue.Dequeue();
                }
            }
        }
        Logdata();
        changeInfoUploaderThread.Abort();
    }
}

here is the sample data of changeInfoQueue queue.

<Info TypeofChange="Add" ObjectType="Customer" ObjectId="0005" />
<Info TypeofChange="Add" ObjectType="Customer" ObjectId="0006" />
<Info TypeofChange="Add" ObjectType="Customer" ObjectId="0007" />
<Info TypeofChange="Add" ObjectType="Photo" ObjectId="01a243f5-4894-4d99-8238-9c4cd3" />

My Question :

  • I need to sort out changeInfoQueue based on ObjectType. How can i do that?

My findings:

  • I found OrderBy . Is it possible to use it? If so, how?

In addition to that I found priorityQueue. What is the best solution for me?

EDIT:

The values of this queue are added when relevant objects are created. (projects, borders etc.) and saves it in a local XML file. After that it needs to write to a database. This is accomplished by using a thread and when we save this data it must be saved in particular order to avoid foreign key violations. So this thread is used to call those relevant methods.

I used orderby as follows:

Queue<ChangeInfo> changeInfoQueue2 = changeInfoQueue.OrderBy(ChangeInfo => ChangeInfo.ObjectType);

then it throws following exception:

Cannot implicitly convert type 'System.Linq.IOrderedEnumerable' to 'System.Collections.Generic.Queue'. An explicit conversion exists (are you missing a cast?)

Grof answered 18/1, 2013 at 10:14 Comment(10)
If you know about OrderBy, please explain how you tried to use it and where you are stuck.Essequibo
A queue is a queue - sorting a queue is pointless. Imagine the queue in the supermarket, where people get called alphabetical... Use a SortedDictionary instead. (Or if you just want to force some special entrys, look at PriorityQueues)Mezzanine
There is no enough details about why you need this, Queue data structure has nothing about sorting, it is a set of items in order they were added, so you need to update queue order itself or just sort items in some temoporary location is fine as well?Facility
You can use Linq. See this article https://mcmap.net/q/1920653/-queue-orderingStatis
Do you really need Queue class? Its main purpose is, after all, to preserve the order in which items were added. Maybe you could use List or some other collection?Infusionism
Just make it IEnumerable<ChangeInfo> changeInfoQueue2`Feverroot
@Facility , - i modified my questionGrof
or "var changeInfoQueue2 = ..."Berberine
IEnumerable<ChangeInfo> also throws exceptionsGrof
No, those messages are compiler errors, not exceptions. Use var.Feverroot
J
15

Why would you want to order by the type of object in a queue? A queue, by its definition, it's not meant to be ordered in that way but intended to work as a first in first out kind of element.

Either use a List if you just want a collection capable of being ordered, and ordered list or create several queues for the different kind of objects that you have.

For example, if you go to the super market you have several queues, one for each different section... it wouldn't make any sense to put all people in the same queue and then "order" them based on whether they are in for the butcher or the bakery.

You have a queue when you need to "queue" things... if you don't use the appropriate construct, don't try to force it into a queue. ("if you have a hammer everything looks like a nail"... but it should not)

Jackelynjackeroo answered 18/1, 2013 at 10:19 Comment(2)
this queue values are added when relevent objects are created. (projects, borders etc) and saved it in locally as a xml file. after that it need to write db. this is done using thread and when we save these data its need to to save in particular order in order to avoid foreign key vialationsGrof
So? Use a list an order it properly. The problem is not that you're trying to solve the wrong problem but you're trying to use a queue for something that's better solved with other data type.Melidamelilot
H
10

While everything that has been said about using queue and OrderBy is valid, you still might want to order elements in your queue.

You can build a new queue based on a IOrderedEnumerable:

Queue<string> queue = new Queue<string>();
queue.Enqueue("first");
queue.Enqueue("second");
queue.Enqueue("third");
queue.Enqueue("fourth");

// Builds a new queue. Items are now alphabetically ordered
Queue<string> orderedQueue = new Queue<string>(queue.OrderBy(z => z));
Hibiscus answered 18/1, 2013 at 10:38 Comment(2)
it says "At least one object must implement IComparable." that means do i need to implement my class using IComparable?Grof
@TilT Yes. Please see this answer for details: https://mcmap.net/q/280805/-at-least-one-object-must-implement-icomparableHibiscus
M
0

The simplest way to achive it is:

Queue priorityQueue = new Queue<int>();

priorityQueue = new Queue<int>(priorityQueue.OrderBy(x => x))

I hope this will help you

Michaella answered 22/9, 2022 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.