tags:

views:

758

answers:

7

Hello,

Unfortunately an item can only be removed from the stack by "pop". The stack has no "remove" method or something similar, but I have a stack (yes I need a stack!) from which I need to remove some elements between.

Is there a trick to do this?

+12  A: 

If you need to remove items that aren't on the top, then you need something other than a stack.

Try making your own implementation of a stack from a List. Then you get to implement your own push and pop functions (add & remove on the list), and your own special PopFromTheMiddle function.

For example

public class ItsAlmostAStack<T>
{
    private List<T> items = new List<T>();

    public void Push(T item)
    {
        items.Add(item);
    }
    public T Pop()
    {
        if (items.Count > 0)
        {
            T temp = items.Last();
            items.Remove(temp);
            return temp;
        }
        else
            return default(T);
    }
    public void Remove(int itemAtPosition)
    {
        items.RemoveAt(itemAtPosition);
    }
}
Binary Worrier
Making a custom implementation around an existing container lets you do all you need to. If you needed a double ended stack (destack) like I did, it also lets you write the most awesome function names: PushBottom(), PopBottom() and PeekBottom() :).
xan
A downvote with no reason? How could this be? Folks if you don't like my answer, or there's something wrong with it could you let me know so I can fix it? We're all here to learn :) Thanks.
Binary Worrier
I'm guessing the downvote had to do with you contradicting the OP's assertion that he does indeed need a stack. For the record, I'm with you. You may need push() and pop(), but if you need other insertion/removal methods, calling it a stack is no longer that meaningful; it supports stack semantics
Matt J
+3  A: 

Consider using different container. Maybe a LinkedList. Then you can use

AddFirst
AddLast
RemoveLast
RemoveFirst

just like pop/push from stack and you can use

Remove

to remove any node from the middle of the list

Michał Piaskowski
+2  A: 

Then it is not a stack right? Stack is LAST in FIRST out. You will have to write a custom one or choose something else.

aJ
What you are talking about is a LIFO stack, but that is not the only kind...
Guffa
What are the other different types of stack?
aJ
He talks about queues, a stack is always LIFO
Enyra
+2  A: 
   Stack temp = new Stack();
   object x, y;
   While ((x = myStack.Pop()) != ObjectImSearchingFor)
       temp.Push(x);
   object found = x;
   While ((y = temp.Pop()) != null)
      myStack.Push(y);
Charles Bretana
I wanted to avoid something like this, perhaps there is a way with LinQ, but seems as I have to do it in this way.
Enyra
A: 

hmmmm...... I agree with the previous two answers but if you are looking to hack your way just pop and save all elements until you get to the one you want, and the re-push them all

Yes is ugly, badly performing, probably weird code that will need a long comment explaining why, but you could do it....

webclimber
+2  A: 

In a true stack, this can only be done one way -

Pop all of the items until you remove the one you want, then push them back onto the stack in the appropriate order.

This is not very efficient, though.

If you truly want to remove from any location, I'd recommend building a pseudo-stack from a List, LinkedList or some other collection. This would give you the control to do this easily.

Reed Copsey
I have two special cases, in one of them the stack has a maximum capacity, but if it's full, the first one will be removed
Enyra
Reed Copsey
There is a Deque class you could modify easily here: http://www.codeproject.com/KB/recipes/deque.aspx
Reed Copsey
+1  A: 

Perhaps an extension method would work, although, I suspect that a different data structure entirely is really needed.

public static T Remove<T>( this Stack<T> stack, T element )
{
     T obj = stack.Pop();
     if (obj.Equals(element))
     {
         return obj;
     }
     else
     {
        T toReturn = stack.Remove( element );
        stack.Push(obj);
        return toReturn;
     }
}
tvanfosson