3

Bizarrely the stack collection seems to be missing the rather basic shift and unshift methods* and I'm working in 2.0 so I can't just extend them.

Is there any reasonable technique or alternative collection class to get these methods available? I need push and pop as well.

Edit: looks like the collection I want is indeed a deque which is happily not native to C# :(

Can't use third party libraries at this time so I'll be going with the clunky LinkedList (I say clunky because reading and removing are two operations where shift would be one) but I think I'd recommend the PowerCollections approach to anyone who could use it. Or better yet, upgrading to extension methods.

sigh


* Apologies, I didn't realise these were uncommon terms, I thought I just didn't know where to find them in the API. For reference:

shift = remove first element

unshift = insert element at beginning of collection

annakata
  • 74,572
  • 17
  • 113
  • 180
  • I've posted a C# implementation of an _immutable deque_ on my blog; you're free to use it for whatever you want. Code is untested! Buyer beware, etc. http://blogs.msdn.com/ericlippert/archive/2008/02/12/immutability-in-c-part-eleven-a-working-double-ended-queue.aspx – Eric Lippert May 11 '09 at 17:12

7 Answers7

15

I would say use a LinkedList<T>. It has methods for adding and removing from the front, as well as adding and removing from the back. I've never heard of shifting and unshifting, but I'm assuming that's what it means.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
BFree
  • 102,548
  • 21
  • 159
  • 201
  • Thank you Marc. Thank you .Net Framework :D !! How easy it is to work with C# compared to many other languages. – Samuel Sep 04 '15 at 18:42
9

Never heard of shift/unshift in a stack. The Stack class does provide Pop, Peek, and Push though.

Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
leppie
  • 115,091
  • 17
  • 196
  • 297
  • 2
    javascript and perl at least have shift/unshift - just the logical opposite of push/pop – annakata May 11 '09 at 13:27
  • 3
    But not part of a traditional 'stack' data structure. – Joel Coehoorn May 11 '09 at 13:34
  • @Annakata: Perl and JavaScript put those methods on arrays, not stack, to enable using arrays as queues, stacks and dequeues. .NET is somewhat more specific in its type system (it is static typed afterall). – Richard May 11 '09 at 14:08
  • JS essentially models all collection types on array cause it's all it's got :) – annakata May 11 '09 at 14:48
6

You are using the wrong class if you want a shift/unshift method. A stack is a Last-In First-Out (LIFO) data structure.

If you want shift/unshift without pop and push, use a Queue. If you want both, I recommend using Deque from the PowerCollections library

Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
1

This is not exactly the best, but it comes close to being a Javascript array with shift/unshift and push/pop. Its does not hide the inner workings, and you can index any item you want. I has the basic functionality though.

 public class JSList<T> : List<T>
{
    public JSList() : base() {}

    /// <summary>
    /// this the add item to the start of the list
    /// </summary>
    /// <param name="v"></param>
    public void Shift(T v)
    {
        this.Insert(0, v);
    }

    /// <summary>
    /// remove item at the start of the list
    /// </summary>
    /// <returns></returns>
    public T Unshift()
    {
        var toreturn = default(T);
        if (this.Count > 0)
        {
            toreturn = this[0];
            this.RemoveAt(0);
        }
        return toreturn;
    }

    /// <summary>
    /// Adds object to end of the list
    /// </summary>
    /// <param name="v"></param>
    public void Push(T v)
    {
        this.Add(v);
    }

    /// <summary>
    /// removes an item at the end of the list
    /// </summary>
    /// <returns></returns>
    public T Pop()
    {
        var toreturn = default(T);
        if (this.Count > 0)
        {
            toreturn = this[this.Count - 1];
            this.RemoveAt(this.Count - 1);
        }
        return toreturn;
    }

    public T Peek()
    {
        return this[this.Count - 1];
    }
}
Gauthier
  • 1,251
  • 10
  • 25
1

You can fake extension methods as long as you are using C# 3.0 targeting 2.0.

Can you describe what the shift/unshift operations are?

Community
  • 1
  • 1
Erich Mirabal
  • 9,860
  • 3
  • 34
  • 39
1

By definition Stack class represents a way of managing elements in a collection using the Last In First Out (LIFO) technique for adding and removing elements. LIFO simply means that the last element added to a collection will automatically be the first one removed.

The functionality you want from it is something custom, but easily can be achieved in following way

public class MyStack<T>:Stack<T>{
  public void Shift(T item){
     // load stack into internal ordered list
     // clear stack content
     // insert into internal list at desired location
     // populate stack with content from internal list
  }
  public void Unshift(T item){
     // load stack into internal ordered list
     // clear stack content
     // insert into internal list at desired location
     // populate stack with content from internal list
  }
}

and seems this it-s all :)

ruslander
  • 3,815
  • 4
  • 32
  • 34
  • I don't see how that will help. Nothing in Stack will give you access to the underlying array to perform those operations. – Erich Mirabal May 11 '09 at 13:56
  • 1
    What I mean to say is that you are turning O(1) operations to O(n) because you don't have access to the underlying data. This is a very ineffective way of doing it, don't you think? – Erich Mirabal May 11 '09 at 14:02
  • May be, but I don't see it painful to play with them (content objects) only changing references order. In the case if the feature is "must have" then it should carefully tested against performance. Again ... is just ordering and even doing Pop and rePush after – ruslander May 11 '09 at 14:28
0
Shift ==> Stack.Pop
Unshift ==> Stack.Push

Unshift doesn't return the number of elements in the Stack, you have the Stack.Count property for that.

Also, there's Stack.Peek, to get the first element without removing it.

Stack<T> class

DonkeyMaster
  • 1,302
  • 4
  • 17
  • 36
  • shift/unshift != push/pop - the former operates at the beginning and the latter at the end of the collection. Quite different. – annakata May 11 '09 at 14:46
  • A Stack is LIFO, so push and pop both operate on the top of the Collection. In Javascript, shift and unshift both operate on the beggining of the array http://www.exforsys.com/tutorials/javascript/javascript-array-object-methods-part-2/1.html – DonkeyMaster May 12 '09 at 14:17