Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change an element in a queue?

Tags:

c#

queue

Let say if I have a queue of integer (or any class T), can I change the value of the element in the queue? More specifically, if I define the queue as follow:

Queue<int> q = new Queue<int>();

Can we change the value of its element similar to how we deal with an array? (if q were an array, we would be able to do something like this: q[0]=1 to change its element). I just would like to simplify the scenario and use int as example, but my intention was trying to peek at the 1st item of a class T in a queue, do some calculations and update the queue for other programs to process. I do not want to dequeue it because it the sequence in the queue will then not be the same as the original. Hope what am trying to do make sense. Please advise.

like image 967
user1205746 Avatar asked Sep 11 '12 14:09

user1205746


People also ask

Can we delete any element from Queue?

To remove an element from a queue, bring that element to the front of the Queue and pop it out using the pop() function.

How do I remove an item from a Queue in Python?

Removing an item from a queue in Python: To remove items from a queue in Python, we will be using the “get function”. See the Python Queue example given below. To make sure that our queue is empty, we can use the empty function which will return Boolean values.

How do I add and remove elements from my Queue?

Insertion and deletion in queues takes place from the opposite ends of the list. The insertion takes place at the rear of the list and the deletion takes place from the front of the list. Insert operation is called push operation. Insert operation is called enqueue operation.

Does Queue have index?

Unlike ArrayList , there is no get(int index) method in Queue to retrieve the element at specified position.


4 Answers

If the item in the queue was a mutable type then you could change the value that the queue has as it's first item. Without re-creating the queue, or performing a lot of enqueues/dequeues there is no way to change which item is at the front of the queue.

As an example of the first case, if you had a Queue<MyClass> with a definition of:

class MyClass
{
    public string Value { get; set; }
}

Queue<MyClass> queue = new Queue<MyClass>();
queue.Enqueue(new MyClass() { Value = "1" });
queue.Peek().Value = 2;
string value = queue.Peek().Value; // is 2
like image 93
Servy Avatar answered Oct 04 '22 02:10

Servy


You can't directly change an item in Queue (although you can use a workaround as Tudor suggested). But if you want to have a queue, you don't have to use Queue. Another possible type from .Net is LinkedList. It allows you to add and remove things from both ends, which can be used in your scenario:

LinkedList<int> list = new LinkedList<int>();

// enqueue an item
list.AddLast(1);

// dequeue an item
var item = list.First.Value;
list.RemoveFirst();

// put item back to the front of the queue
list.AddFirst(item);

It seems you want to do this to process each item by several modules in sequence. But I'm not sure this is the right way to do this kind of work. A better way might be to have a queue between each two modules. A module would always take an item from its input queue, process it and then put it in its output queue.

One of the advantages of this approach is greater flexibility: a module can have different type on the output than on the input, which is not possible with the “one queue” approach (unless you resort to having a queue of objects, or something like that).

TPL Dataflow (new in .Net 4.5) uses this approach to improve performance through parallelization. It can do that, because each module can process items independently of other modules if you don't have a single central queue.

like image 27
svick Avatar answered Oct 04 '22 00:10

svick


As long as you're storing a reference type like a class, any changes you make to it will be reflected in the Queue. The output of the code below will be "2":

    public class MyClass
    {
        public int Value { get; set; }
    }

    static void Main(string[] args)
    {
        Queue<MyClass> q = new Queue<MyClass>();
        q.Enqueue(new MyClass { Value = 1 });
        var i = q.Peek();
        i.Value++;
        i = q.Peek();
        Console.WriteLine(i.Value);
    }
like image 41
Mike Payne Avatar answered Oct 04 '22 02:10

Mike Payne


You could use a simple wrapper:

class Wrapper<T>
{
    public T Value { get; set; }
}

static void Main(string[] args)
{
    Queue<Wrapper<int>> q = new Queue<Wrapper<int>>();
    Wrapper<int> wr = new Wrapper<int> { Value = 1 };
    q.Enqueue(wr);

    Wrapper<int> wr1 = q.Peek();
    wr1.Value = 2;

    int value = q.Dequeue().Value;
    Console.WriteLine(value);
}
like image 32
Tudor Avatar answered Oct 04 '22 02:10

Tudor