How to "Dequeue" Element from a List?
C#ArraysC# Problem Overview
I have a List
of cards called _deck:
private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }
And then I want to remove a card from the List
and save into a variable. I'm trying to do:
String p1FirstCard = _deck.RemoveAt(0);
but I'm getting the error
> Cannot convert type void to String
In C# List
is there something like push/pop but which does that at the "head" or "start" of the List
? (Push/pop works at the "tail" or "end" of the list.)
If not, how should I do remove the first element but save it in a variable?
C# Solutions
Solution 1 - C#
If you want to dequeue the first element, you could simply use a Queue<T>
.
class Program
{
static void Main(string[] args)
{
var _deck = new Queue<String>();
_deck.Enqueue("2h");
_deck.Enqueue("3h");
_deck.Enqueue("4h");
_deck.Enqueue("...");
var first = _deck.Dequeue(); // 2h
first = _deck.Dequeue(); // 3h
}
}
If you want to pop the last element, you could use a Stack<T>
.
class Program
{
static void Main(string[] args)
{
var _deck = new Stack<String>();
_deck.Push("2h");
_deck.Push("3h");
_deck.Push("4h");
_deck.Push("...");
var first = _deck.Pop(); // ...
first = _deck.Pop(); // 4h
}
}
Solution 2 - C#
You can do it in two steps:
String p1FirstCard = _deck[0];
_deck.RemoveAt(0);
You can write your own extension helper method (I added an index to Pop
, as @Fredou suggested:
static class ListExtension
{
public static T PopAt<T>(this List<T> list, int index)
{
T r = list[index];
list.RemoveAt(index);
return r;
}
}
and then call
String p1FirstCard = _deck.PopAt(0);
P.S. The name can be a bit confusing. Pop
usually removes the last element, not the first one.
Solution 3 - C#
If you want a direct equivalent to pop()
, you'll have to write your own, because I don't think a List
has a "Remove from end and return". However, there are both the Queue
(first in, first out) and the Stack
(first in, last out) classes instead of just a List
.
There's also the LinkedList
class which lets you add to or remove from both the beginning or the end, but the provided RemoveFirst()
and RemoveLast()
methods don't automatically return the item being removed - you'd need to write an extension method like AlexD's to do that.
All of these deal with removing things from the beginning or the end of the list. If you just want to remove an arbitrary item from the middle of a List
, there's always List.Remove(item)
which removes a specific item from the list (rather than by position).
Solution 4 - C#
Building on AlexD's answer, I added a couple more extension methods:
public static class ListExtensionMethods
{
public static T PopAt<T>(this List<T> list, int index)
{
var r = list[index];
list.RemoveAt(index);
return r;
}
public static T PopFirst<T>(this List<T> list, Predicate<T> predicate)
{
var index = list.FindIndex(predicate);
var r = list[index];
list.RemoveAt(index);
return r;
}
public static T PopFirstOrDefault<T>(this List<T> list, Predicate<T> predicate) where T : class
{
var index = list.FindIndex(predicate);
if (index > -1)
{
var r = list[index];
list.RemoveAt(index);
return r;
}
return null;
}
}
Solution 5 - C#
private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }
//Save into variable first
String p1FirstCard = _deck[0];
//Now just remove it
_deck.RemoveAt(0);
RemoveAt(int)
doesn't return anything.