【问题标题】:How to delete a chosen element in array?如何删除数组中选定的元素?
【发布时间】:2011-11-07 03:16:10
【问题描述】:

我有这个任务,我必须从数组中删除一个选定的元素,所以我想出了这个代码:

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

问题是,假设我有一个数组[1,2,3,4,5,],我想删除1。输出将是[2,3,4,5,5]。当我选择2 时也会发生这种情况,但当我选择任何其他号码时不会发生这种情况。

我做错了什么?

【问题讨论】:

  • intAmountstrItems 是什么?您在 for 循环中对 for 循环索引进行了大量操作,这通常是个坏主意。
  • 你能澄清你的问题吗:你说[1,2,3,4,5],用删除1的操作,变成[2,3,4,5,5]。你如何选择 5 作为最后复制的元素?
  • strItems 为字符串数组,intAmount 为元素个数,strInput 为用户选择删除的元素。
  • 我没有选择5进行复制,这是我遇到的问题。

标签: c# arrays


【解决方案1】:

我假设您正在使用基本的字符串数组:

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

在 .NET 中,该数组的长度始终为 5 个元素。为了删除一个元素,您必须将剩余的元素复制到一个新数组并返回它。将某个位置的值设置为null 不会将其从数组中删除。

现在,使用 LINQ 之类的东西非常容易(此处未显示),或者您可以使用 List&lt;&gt; 集合作弊并执行以下操作:

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

但我认为这不会教给你任何东西。

第一步是找到要删除的元素的索引。您可以使用Array.IndexOf 来帮助您。让我们找到中间元素“3”:

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

如果没有找到该元素,它将返回 -1,所以在做任何事情之前检查它。

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

最后,您必须将元素(除了我们不想要的索引处的元素)复制到一个新数组中。所以,总的来说,你最终会得到这样的东西(评论解释):

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

现在strItems 将是新数组,减去指定要删除的值。

【讨论】:

  • 哇!多么完整和解释性的答案!
【解决方案2】:

C# 中的数组具有固定大小 - 一旦初始化,您只能修改项目,但您不能添加或删除项目。如果你想从集合中删除一个项目,你有两个选择:

1.) 创建一个新数组,其中包含原始数组的所有成员减去您要删除的成员。

2.) 使用可调整大小并允许添加或删除项目的集合类型,例如List&lt;T&gt;(在您的情况下为List&lt;int&gt;)。如果您的收藏不是静态的,这就是您在“现实世界”中所做的事情。

【讨论】:

    【解决方案3】:

    在您的具体实现中,我认为您错过了break; 语句,当您完成内循环时,您应该从外循环退出。赋值给 null 一点用处都没有。

    如果列表只是数字列表,为什么要使用字符串?如果是这种情况,直接使用整数。

    如果您只需要删除一个元素,您的练习似乎会问这样的问题。

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

    如果找到指定的值,该函数将返回true,否则返回false。 它将按照您在示例中描述的那样移动所有项目,但当然,它不会改变数组的大小。

    数组是固定大小的。 您不能更改数组的大小,简单地说,语言不允许这样做。 数组现在、过去和将来都是固定大小的!

    要从数组中删除一个项目,你应该这样做:

    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);
    

    此函数将创建一个新数组,其中包含除您指定的索引处的元素之外的所有元素。

    现在,为什么有人会做这样的事情而不是使用列表或字典或 wathever? 直接使用List而不使用数组。

    【讨论】:

      【解决方案4】:

      可以使用Except方法过滤数据

      AllData = {10, 30, 20, 50}
      
      FilterData = {30, 20}
      
      Result = AllData.Except(​FilterData) 
      

      结果将是{10, 50}

      【讨论】:

        【解决方案5】:
        • 数组是固定大小的,如果不创建新数组,就无法缩短它们的长度。您所能做的就是将 valid 元素的长度存储在数组中(即,删除 1 后,长度为 4)。

          另外,我不确定数组中元素的顺序是否重要,但如果不是,您可以交换第一个和最后一个元素,而不是将每个元素移到前 1 个位置之后。

        • 使用数组的另一种方法是使用集合,例如 ArrayList,它将负责调整大小、删除和保留其中项目数量的计数,以及更多。

        • 但是,由于这是家庭作业,您可能必须使用数组。要么使用变量跟踪长度,而不是使用array.length,要么在每次要更改大小时创建一个新数组。如果您不必使用数组,请查看可以在 C# 中使用的集合。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 2012-06-15
          • 2012-03-29
          • 2016-11-11
          • 2011-01-27
          相关资源
          最近更新 更多