sort a queue in C#
Solution 1
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)
Solution 2
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));
Comments
-
DevT almost 2 years
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?)
-
Oded over 11 yearsIf you know about
OrderBy
, please explain how you tried to use it and where you are stuck. -
dognose over 11 yearsA 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)
-
sll over 11 yearsThere 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?
-
subprime over 11 yearsYou can use Linq. See this article stackoverflow.com/questions/561644/queue-ordering
-
Arie over 11 yearsDo 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?
-
Henk Holterman over 11 yearsJust make it
IEnumerable<ChangeInfo>
changeInfoQueue2` -
DevT over 11 years@sll , - i modified my question
-
2GDev over 11 yearsor "var changeInfoQueue2 = ..."
-
DevT over 11 yearsIEnumerable<ChangeInfo> also throws exceptions
-
Henk Holterman over 11 yearsNo, those messages are compiler errors, not exceptions. Use
var
.
-
DevT over 11 yearsthis 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 vialations
-
Jorge Córdoba over 11 yearsSo? 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.
-
DevT over 11 yearsit says "At least one object must implement IComparable." that means do i need to implement my class using IComparable?
-
ken2k over 11 years@TilT Yes. Please see this answer for details: stackoverflow.com/a/14141926/870604