Can I limit the depth of the overall stack?

Is there a built-in way to limit the depth of System.Collection.Generics.Stack? So, if you're at maximum capacity, clicking on a new item will delete the bottom of the stack?

I know that I can do this by transforming the array and rebuilding the stack, but I decided that perhaps there is already a method for it.

EDIT: I wrote an extension method:

public static void Trim<T> (this Stack<T> stack, int trimCount) { if (stack.Count <= trimCount) return; stack = new Stack<T> ( stack .ToArray() .Take(trimCount) ); } 

So, it returns a new stack when trimming, but the functional path is not immutable =)

The reason for this is that I save the undo steps for the application on the stack, and I only want to save a finite number of steps.

+4
source share
5 answers

What you are looking for is called a dropdown stack . AFAIK, BCL does not contain one, although they are trivial to implement. As a rule, the functionality of Undo and Redo is based on such data structures.

They are basically an array, and when you click on the stack, the "top" of the stack moves around the array. In the end, the top will return to the beginning when the stack is full and replace the "bottom" stack.

Google did not provide much information about this. This is the best I could find:

(Warning PDF) http://courses.cs.vt.edu/~cs2704/spring04/projects/DropOutStack.pdf

Here is the boiler plate code to get you started. I will let you fill in the rest (health check, count, indexer, etc.).

 class DropOutStack<T> { private T[] items; private int top = 0; public DropOutStack(int capacity) { items = new T[capacity]; } public void Push(T item) { items[top] = item; top = (top + 1) % items.Length; } public T Pop() { top = (items.Length + top - 1) % items.Length; return items[top]; } } 
+16
source

In fact, you are looking at something similar to implementing a circular list. There the LimitedQueue implementation is implemented by PIEBALDconsult in CodeProject. This is similar to your requirement. You just need to wrap Stack instead of Queue, as the author did. In addition, the author also implemented an index, which is convenient if you need to access anything other than the top stack (possibly display a cancellation list).

EDIT: The author’s implementation also leads to an event when the latter (firstly, depends on whether the queue or the stack has been deleted) so that you can know when something is thrown.

+3
source

For someone else who comes across this issue while trying to limit their sizes for undo / redo, here is the best solution (uses LinkedList):

Limit total collection size

+2
source

I do not see the way. You can inherit from Stack<T> , but there is nothing useful for redefinition.

The easy (if a little tedious) way is to wrap the Stack<T> in your own, say LimitedStack<T> . Then execute the necessary methods and go to the internal Stack<T> , including your limiting logic in the Push method and wherever you need it.

It pains me to write all these end-to-end elements, especially if you implement all the same interfaces as Stack<T> ... but, on the other hand, you only need to do this once and then do it.

+1
source

I believe that you are looking for a (possibly modified) dequeue - a data structure that allows access from either end.

+1
source

All Articles