Removing the last item from a queue in C# - c#

We have the Enqueue and Dequeue methods to work on a queue in C#.
But is there a way we can remove the last item in the queue? Dequeue actually removes the item from the top.

The entire purpose of a Queue is to walk the collection from top to bottom. If you want a collection type that allows removing from the back too (or any place in the collection), use another collection type, a List<T> for example.

Maybe you should consider using a Stack instead of a Queue.
Stack works similar to a queue but instead of the first in first out behaviour a stack is used when you need a last in first out solution for your objects

This is an expensive operation, so I only do this rarely. People here getting mad and not answering... all you do is just use a second Queue to move everything to:
// original queue must already be filled up
Queue<Waypoint> waypoints = new Queue<Waypoint>();
// fill it up...
Queue<Waypoint> temp = new Queue<Waypoint>();
while (waypoints.Count > 0) // stop one short of the end
{
temp.Enqueue(waypoints.Dequeue());
}
Waypoint wp = waypoints.Dequeue();
// get the last one and do what you desire to it...
// I modified mine and then added it back, this is not needed
temp.Enqueue(new Waypoint(wp.pos, (p.vectorPath[0] - wp.pos).normalized));
// necessary: you have waypoints empty now so you have to swap it for temp:
waypoints = temp;

Like Patrick stated the queue is meant to be first in first out. Think of it like a printer queue, the first page that goes to into the printer queue is the first to be printed out.
Look into using a List instead of an Array, I found lists a bit easier to manipulate with a bunch of extended methods that arrays do not have.
http://www.dotnetperls.com/list
Here is a link to how to remove the last item in a list which has a few different ways of accomplishing it.
How to remove the last element added into the List?
hope this helps!

Related

Add range of elements to new list in C#

New programmer here. I'm trying to add a range of elements to a new list in C#. This is for a game I'm making in Unity. It's a game based on the old nokia Snake game, where each time the snake eats a fruit it gets longer. This information is stored in a list in my game. Now the thing is I'm trying to create a game element where at a certain point all the nodes from the snake (the tail basically) break away from the snake itself, and the snake has 3 elements remaining (the head, body, and a tail). I got it to work perfectly fine, except for the fact I can't get the range of nodes in the list to transfer to the newNode list for the life of me.
for (int i = 0; i < nodes.Count; i++)
{
if (nodes.Count > 3)
{
newNodes.Add(nodes[4]);
newNodes.Add(nodes[5]);
newNodes.Add(nodes[6]);
newNodes.AddRange(nodes[3], nodes.Count - 3);
nodes.RemoveRange(3, nodes.Count - 3);
}
When I run the game, the expected behavior works for the newNodes.Add (individual nodes). But what I would like is to see happen is something along the lines of newNodes.AddRange(nodes[3], nodes.Count - 3); But that doesn't work. How can I get it so it reads the nodes from 3 or 2 or whatever value to the total nodes in the list. I've been stuck on this for days! Really could use some help/input.
The code above is not complete, it's part of a coroutine actually that should get called after certain criteria has been met. It's just that I wonder if there's any way to do this?
Using the LINQ extension method Skip you can skip over the first part of a list and get the rest. As it is an extension method, you first need this near the top of your code file:
using System.Linq;
Then you can use this to add all but the first three items to the new list:
newNodes.AddRange(nodes.Skip(3));
Note: this doesn't change "nodes" in any way.
Bonus: if "nodes" contains 3 items or less, this will not fail (but of course add nothing to newNodes)
Try this :
newNodes.InsertRange(newNodes.Count - 1, nodes.GetRange(3, nodes.Count - 3));
nodes.RemoveRange(3, nodes.Count - 3);
If newNodes is empty, you need to make sure to pass 0 as index instead of
newNodes.Count - 1
As said, I'm a new programmer and have never used Stackoverflow. I'm truly overwhelmed by all the responses in such a short time, thank all for taking the time to read my question and trying to figure it out with me.
The code that seemed to work in my case was
newNodes.InsertRange(newNodes.Count, nodes.GetRange(3, nodes.Count - 3));
It basically captures all the nodes (snake bodies) in the list and releases them properly in a new list!
Again thanks!!
The problem is when you use
newNodes.AddRange(nodes[3], nodes.Count - 3);
you're only providing the single node at index 3. AddRange expects an IEnumerable, not a single object from a list. To get an IEnumerable you have to use the GetRange or LINQ methods that have already been posted by others.

Native Array, Stack, ArrayList or List for creating 'low pass' filter

Trying to create a type of low pass filter where I constantly average the previous 10 float values. Not sure whether to use builtin arrays (native .NET arrays), the .NET Stack operator, or perhaps an ArrayList or List.
In pseudocode I need to
1- Define the array or Stack containing 10 floats
2- Every update Push a new value to the Array, Stack, List
3- Check the length and if greater than10 remove the first or oldest float value from the Array, Stack, List
4- Get the average of all float values in the Array, Stack, List
5- Repeat steps 2-4
1st question Should I be using built in Arrays, Stack, ArrayList or List instead? I notice in the Stack documentation there is no method for removing the oldest (bottom)item from the stack, but perhaps I am missing something
https://msdn.microsoft.com/en-us/library/3278tedw(v=vs.100).aspx
What I need is all the functionality of the (Javascript only) Array class but in C#.
2nd Can anyone help with actual syntax using either approach? Any help appreciated!
You've probably missed the Queue data structure. With it, you can put new elements to the end and delete old ones from the front.
Additionally, you don't need to look at all the elements in the array to compute the average if there are constantly 10 elements. Knowing the previous average you can compute the new average like this:
newAvg = oldAvg + (newElem - deletedElem)/10;
or more shortly:
avg += (newElem - deletedElem)/10;
You could use the generic Queue<T> collection to store the values:
var queue = new Queue<float>();
queue.Enqueue(1.0f); // pushes new item
queue.Dequeue(); // removes oldest item
To obtain the average, use the LINQ Average() extension method:
var average = queue.Average();
Stacks are LIFO(Last In First Out).
If you want to remove the oldest value, then you'd want to use a queue (First In First Out).

how properly remove item from list [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Exception during iteration on collection and remove items from that collection
How to remove elements from a generic list while iterating around it?
Better way to remove matched items from a list
// tmpClientList is List<Client> type
if (txtboxClientName.Text != "")
foreach (Client cli in tmpClientList)
if (cli.Name != txtboxClientName.Text)
tmpClientList.Remove(cli);
Error: "Collection was modified; enumeration operation may not execute."
How can i remove items from the list, in some simple way, without saving indexes of these items in another list or array, and removing them in another place in the code. Tried also RemoveAt(index) but it's exactly the same situation, modifying when loop runs.
Move backwards through the list.. that way removing an item does not affect the next item.
for(var i=tmpClientList.Count-1;i>=0;i--)
{
if (tmpClientList[i].Name != txtboxClientName.Text)
tmpClientList.RemoveAt(i);
}
On a List<T>, there is a RemoveAll method that takes a delegate to indicate whether to remove the item. You can use it like this:
tmpCLientList.RemoveAll(cli => cli.Name != txtboxClientName.Text);
Either use a for/while loop, or tmpClientList.RemoveAll(a => a.Name == txtboxClientName.Text). As you didn't specify which c# version you are using, ymmw.
Don't use foreach. Use for and descend the list (i.e. start from the end), using RemoveAt.
So,
// tmpClientList is List<Client> type
if (txtboxClientName.Text != "")
foreach (int pos = tmpClientList.Length - 1; pos >= 0; pos--)
{
Client cli = tmpClientList[pos];
if (cli.Name != txtboxClientName.Text)
tmpClientList.RemoveAt(pos);
}
The problem is that you are trying the modify the list in a foreach iteration. Replace that with a for and you should be ok.
Also, since you seem to be using user input for the name, consider cleaning up the input a bit, at least with a Trim() to remove extra white spaces. If you don't, 'John ' and 'John' will be two different things.
Same for the initial != "" check.
You can create another list with the items you want to delete and iterate the new list to remove items from your "txtboxClientName" list.
Actually, foreach uses Enumerators to iterate through given Item-Collections. Going further the System.Collections.Generic.List<T> implements the IEnumarable-Interface to provide a Class, that knows how to iterate through the items of the list, i.e. the Enumerator. Now if you iterate through that list by using foreach the Enumerator keeps track of the current position, how to reach the next position and some other stuff. The internal logic could be something like storing the number of items in a variable n and then access all objects from 0 to n-1. As you may notice if any object is removed between the iteration steps we shall end in a NullReferenceException when the Enumerator tries to deliver the last object of the list. So to prevent any iteration failures, the list itself is not allowed to be modified during Enumeration.
Hope I was able to state that out at least a little bit comprehensively. :-)

How to shift items in an array?

I have an array of items that are time sensitive. After an amount of time, the last item needs to fall off and a new item is put at the beginning.
What is the best way to do this?
I would suggest using a queue, just a special instance of an array or list. When your timed event occurs, pop the last item from the queue, and then push your new item on.
Probably the easiest way to do this with an array is to use a circular index. Rather than always looking at array[n], you would reference array[cIndex] (where cIndex referrs to the item in the array being indexed (cIndex is incremented based on the arraySize (cIndex % arraySize)).
When you choose to drop the oldest item in the array, you would simply reference the element located at ((cIndex + (arraySize - 1)) % arraySize).
Alternatively, you could use a linkedList approach.
Use a Queue instead.
By using a Queue, preferably one implemented using a linked-list.
Have a look at using a Queue rather than a simple array.
A queue would work if there a fixed number of items.
Given that the 'amount of time' is known, how about a SortedDictionary with a DateTime key and override the Add method to remove all items with keys that are too old.
LinkedList<T> has AddFirst and RemoveLast members that should work perfectly.
EDIT: Looking at the Queue docs, it seems they use an internal array. As long as the implementation uses a circular-array type algorithm performance should be fine.
In csharp 3 you can do:
original = new[] { newItem }.Concat(
original.Take(original.Count() - 1)).ToArray()
But you are probably better off using a specialised datastructure
Queue is great for FIFO arrays. For generic array handling, use List(T)'s
Insert(0, x) and RemoveAt(0) methods to put or remove items in front of the list, for example.
Technically you need a deque. A queue has items pushed and popped off one end only. A deque is open at both ends.
Most languages will allow array manipulation, just remove the first element and put another one on the end.
Alternatively you can shift every element, by looping. Just replace each element (starting from the oldest) with its neighbour. Then place the new item in the last element.
If you know that your deque won't go above a certain size, then you can make it circular. You'll need two pointers to tell you where the two ends are though. Adding and removing items, will increase/decrease your pointers accordingly. You'll have to detect a buffer overflow condition (i.e. your pointers 'cross'). And you'll have to use modular arithmetic so your pointers go in a circle around the array.
Or you could time stamp each element in the array and remove them when they become too 'old'. You can either do this by keeping a separate array indexed in the same way, or by having an array of two element arrays, with the time stamp stored in one of the sub-elements.
If you're looking for the fastest way of doing this, it's going to be a circular array: you keep track of your current position in the array (ndx), and the end of the array (end), so when you insert an item, you implicitly eliminate the oldest item.
A circular array is the fastest implementation of a fixed-size queue that I know of.
For example, in C/C++ it would look like this for ints (quitting when you get a 0):
int queue[SIZE];
int ndx=0; // start at the beginning of the array
int end=SIZE-1;
int newitem;
while(1){
cin >> newitem;
if(!newitem) // quit if it's a 0
break;
if(ndx>end) // need to loop around the end of the array
ndx=0;
queue[ndx] = newitem;
ndx++
}
Lots of optimization could be done, but if you want to built it yourself, this is the fastest route.
If you don't care about performance, use a shipped Queue object because it should be generalized.
It may or may not be optimized, and it may not support a fixed size list, so be sure to check the documentation on it before using.

Rotating/moving objects

I have a situation that I am not quite sure where to start looking. I have been searching for the past four hours and I couldn't find anything that does what I am looking to do.
I have eight objects controlling individual lights. When an event occurs I generate an ID of it, store that value in the first available object, and start a method. I also store the ID in a list and match the object number to the index number of that list. What I would like to do is have those eight objects update and rotate depending if the matching item is removed from the list.
Example: There are five out of the eight objects active and I remove an item from the list indexed at 0. Object 0 is stopped then object 1 is moved to object 0 then 2 to 1, 3 to 2, etc.
So my question is what terms should I look up to help me accomplish that goal? I am relatively new to c# and with the results of my research today I just want to know what is the right question to ask.
If what I am looking to do is impossible just say so and I will come up with a more simple program on my end. Or if you have a solution to that situation I am all ears.
I think you're just describing a [stack data structure](https://en.wikipedia.org/wiki/Stack_(abstract_data_type). Check it out and see if it's what you're looking for.
A stack doesn't "rotate" objects, but when you remove the top item, the "index" of all the other items will decrement as you described. In your example, it seems like the list would eventually become empty (after 8 events) which is consistent with a stack - but it's not clear why one would call this rotation.
If a stack is what you're looking for, the BCL defines a generic Stack<T> that can do this. You add items to a stack with the Push() operation, which has the side effect of incrementing the index of all other items in the structure. The dual Pop operation removes the top item from the collection and decrements the index of the other items, as you described.

Categories