web-dev-qa-db-fra.com

Comment supprimer un élément choisi dans un tableau?

J'ai cette affectation où je dois supprimer un élément choisi d'un tableau, alors je suis venu avec ce code:

strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
    if (strItems[i] == strInput)
    {
        strItems[i] = null;
        for (int x = 0; x < intAmount-i; x++)
        {
            i = i + 1;
            strItems[i - 1] = strItems[i];
        }
        intAmount = intAmount - 1;
    }
}

Le problème est que, supposons que j'ai un tableau [1,2,3,4,5,] et que je veux supprimer 1. La sortie serait [2,3,4,5,5]. Cela se produit également lorsque je choisis 2, mais pas lorsque je choisis un autre numéro. 

Qu'est-ce que je fais mal?

13
user1033065

Je suppose que vous travaillez avec un tableau de base de chaînes:

var strItems = new string[] { "1", "2", "3", "4", "5" };

Dans .NET, ce tableau aura toujours 5 éléments de long. Pour supprimer un élément, vous devrez copier les éléments restants dans un nouveau tableau et le renvoyer. Définir la valeur à une position sur null ne la supprime pas du tableau.

Maintenant, avec des choses comme LINQ c'est très facile (non montré ici), ou vous pouvez tricher en utilisant la collection List<> et faire ceci:

var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();

Mais je ne pense pas que cela va vous apprendre quelque chose.

La première étape consiste à rechercher l'index de l'élément que vous souhaitez supprimer. Vous pouvez utiliser Array.IndexOf pour vous aider. Trouvons l'élément du milieu, "3":

int removeIndex = Array.IndexOf(strItems, "3");

Si l'élément n'a pas été trouvé, il retournera -1, alors vérifiez-le avant de faire quoi que ce soit.

if (removeIndex >= 0)
{
     // continue...
}

Enfin, vous devez copier les éléments (sauf celui de l'index que nous ne voulons pas) dans un nouveau tableau. Donc, au total, vous vous retrouvez avec quelque chose comme ceci (commenté pour explication):

string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };

int removeIndex = Array.IndexOf(strItems, strInput);

if (removeIndex >= 0)
{
    // declare and define a new array one element shorter than the old array
    string[] newStrItems = new string[strItems.Length - 1];

    // loop from 0 to the length of the new array, with i being the position
    // in the new array, and j being the position in the old array
    for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
    {
        // if the index equals the one we want to remove, bump
        // j up by one to "skip" the value in the original array
        if (i == removeIndex)
        {
            j++;
        }

        // assign the good element from the original array to the
        // new array at the appropriate position
        newStrItems[i] = strItems[j];
    }

    // overwrite the old array with the new one
    strItems = newStrItems;
}

Et maintenant, strItems sera le nouveau tableau, moins la valeur spécifiée pour la suppression.

37
Cᴏʀʏ

Les tableaux en C # ont une taille fixe - une fois initialisés, vous ne pouvez modifier que les éléments, mais vous ne pouvez pas ajouter ou supprimer des éléments Si vous souhaitez supprimer un élément d'une collection, vous avez deux options:

1.) Créez un nouveau tableau contenant tous les membres du tableau d'origine moins celui que vous souhaitez supprimer.

2.) Utilisez un type de collection redimensionnable et permettant d’ajouter ou de supprimer des éléments tels que List<T> (List<int> dans votre cas). C'est ce que vous feriez dans le "monde réel" si votre collection n'est pas statique.

4
BrokenGlass

Dans votre implémentation spécifique, je pense que vous manquez une instruction break;, vous devriez sortir de la boucle externe lorsque vous avez terminé la boucle interne. L'affectation à null n'est pas du tout utile.

Si la liste est juste une liste de nombres, pourquoi utilisez-vous des chaînes? utilisez des nombres entiers directement si c'est le cas.

Votre exercice semble demander quelque chose comme ceci, si vous avez besoin de supprimer un seul élément.

public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
    bool found = false;
    for (int i = 0; i < array.Length; ++i)
    {
        if (found)
        {
            array[i - 1] = array[i];
        }
        else if (array[i] == value)
        {
            found = true;
        }
    }
    return found;
}

Cette fonction retournera true si elle trouve la falue spécifiée, false sinon sinon . Elle déplacera tous les éléments comme vous le décrivez dans votre exemple, mais bien sûr, cela ne changera pas la taille du tableau.

Les tableaux ont une taille fixe . Vous ne pouvez pas changer la taille d'un tableau, simplement, la langue ne le permet pas . Les tableaux sont, ont été et seront toujours de taille fixe!

Pour supprimer un élément d'un tableau, vous devriez faire quelque chose comme ceci:

public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
    int count = array.Length - 1;
    T[] result = new T[count];

    if (index > 0)
        Array.Copy(array, 0, result, 0, index - 1);
    if (index < size)
        Array.Copy(array, index + 1, result, index, size - index);

    return result;
}

...
strItems = RemoveAt(strItems, index);

Cette fonction créera un nouveau tableau contenant tous les éléments sauf celui de l'index que vous spécifiez.

Maintenant, pourquoi quelqu'un ferait-il quelque chose comme ceci au lieu d'utiliser une liste, un dictionnaire ou quoi que ce soit? Utilisez directement une liste sans utiliser de tableau.

3

Peut utiliser la méthode Except pour filtrer les données

AllData = {10, 30, 20, 50}

FilterData = {30, 20}

Result = AllData.Except(​FilterData) 

Le résultat sera {10, 50}

2
Srini
  • Les tableaux ont une taille fixe, vous ne pouvez pas les raccourcir sans créer un nouveau tableau. Tout ce que vous pouvez faire est de stocker la longueur des éléments valid dans le tableau (c'est-à-dire qu'après avoir supprimé 1, la longueur est de 4).

    De plus, je ne suis pas sûr que l'ordre des éléments dans votre tableau soit important, mais si ce n'est pas le cas, vous pouvez échanger les premier et dernier éléments plutôt que de déplacer chaque élément après celui qui est supprimé d'une position.

  • Une alternative à l'utilisation d'un tableau consiste à utiliser une collection telle que ArrayList qui se chargera du redimensionnement, de la suppression et de la comptabilisation de la quantité d'éléments qu'il contient, ainsi que de bien plus encore.

  • Cependant, comme il s’agit d’un devoir, vous devrez peut-être utiliser des tableaux. Vous pouvez soit suivre la longueur avec une variable, par opposition à array.length, soit créer un nouveau tableau chaque fois que vous souhaitez modifier la taille. Si vous n'avez pas à utiliser de tableaux, examinez les collections que vous pouvez utiliser en C #.

1
AusCBloke