web-dev-qa-db-fra.com

Comment "extraire" un élément d'une liste?

J'ai une liste de cartes appelée _deck:

 private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }

Et puis je veux supprimer une carte de la liste et enregistrer dans une variable. J'essaie de faire:

 String p1FirstCard = _deck.RemoveAt(0);

mais j'obtiens le message d'erreur "Impossible de convertir le type vide en chaîne".

Dans C # List, y a-t-il quelque chose comme Push/pop mais que fait-il en "tête" ou "début" de la liste? (Push/pop fonctionne à la fin ou à la fin de la liste.)

Sinon, comment dois-je supprimer le premier élément et le sauvegarder dans une variable?

45
Mc' Flips

Vous pouvez le faire en deux étapes:

String p1FirstCard = _deck[0];
_deck.RemoveAt(0);

Vous pouvez écrire votre propre méthode d'assistance d'extension (j'ai ajouté un index à Pop, comme l'a suggéré @Fredou:

static class ListExtension
{
    public static T PopAt<T>(this List<T> list, int index)
    {
        T r = list[index];
        list.RemoveAt(index);
        return r;
    }
}

et ensuite appeler

String p1FirstCard = _deck.PopAt(0);

P.S. Le nom peut être un peu déroutant.Pop supprime généralement le dernier élément, pas le premier.

40
AlexD

pourriez-vous simplement utiliser le classe de file d'attente que c # a déjà?

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
    }
}

ou pourriez-vous simplement utiliser le classe Stack que c # a déjà?

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
    }
}
42
Fredou

En me basant sur la réponse d’AlexD, j’ai ajouté quelques méthodes d’extension supplémentaires:

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;
    }
}
4
orad

Si vous voulez un équivalent direct de pop(), vous devrez écrire le vôtre, car je ne pense rien en C # automatiquement a un "Retirer de la fin et revenir". Cependant, il existe à la place les classes Queue (premier entré, premier sorti) et Stack (premier entré, dernier sorti) d'un simple List.

Il y a aussi la classe LinkedList qui vous permet d'ajouter ou de supprimer du début ou de la fin, mais les RemoveFirst() et RemoveLast() fournies les méthodes ne renvoient pas automatiquement l'élément en cours de suppression - vous devez écrire une méthode d'extension comme celle d'AlexD pour le faire.

Tous ces éléments concernent la suppression d'éléments du début ou de la fin de la liste. Si vous souhaitez simplement supprimer un élément arbitraire du milieu d'un List, il y a toujours List.Remove(item) qui supprime un élément spécifique de la liste (plutôt que par position).

4
Bobson
 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 () ne renvoie rien.

0
BurnOut