删除常规数组的元素

leo*_*ora 123 .net c# arrays

我有一个Foo对象数组.如何删除数组的第二个元素?

我需要类似于RemoveAt()常规数组的东西.

And*_*nan 186

如果您不想使用List:

var foos = new List<Foo>(array);
foos.RemoveAt(index);
return foos.ToArray();
Run Code Online (Sandbox Code Playgroud)

您可以尝试我尚未测试过的扩展方法:

public static T[] RemoveAt<T>(this T[] source, int index)
{
    T[] dest = new T[source.Length - 1];
    if( index > 0 )
        Array.Copy(source, 0, dest, 0, index);

    if( index < source.Length - 1 )
        Array.Copy(source, index + 1, dest, index, source.Length - index - 1);

    return dest;
}
Run Code Online (Sandbox Code Playgroud)

并使用它像:

Foo[] bar = GetFoos();
bar = bar.RemoveAt(2);
Run Code Online (Sandbox Code Playgroud)

  • 这个答案中给出的第一个例子比第二个例子效率低得多.它需要两个数组副本,并且在索引之后移动所有内容而不是一个选择性数组副本. (8认同)
  • 当然+1,但我们也可以使用列表OR List <Foo> list = new List <Foll>(GetFoos()); list.Remove(my_foo); list.RemoveAt(2); GetFoos()将返回Foos数组!!!! (2认同)
  • 方法内的第一行应该是'source.Length'而不是'array.Length'. (2认同)

Seb*_*etz 63

数组的本质是它们的长度是不可变的.您无法添加或删除任何数组项.

您必须创建一个较短的元素的新数组,并将旧项目复制到新数组,不包括要删除的元素.

所以最好使用List而不是数组.

  • 将数组转换为列表`List <mydatatype> array = new List <mydatatype>(arrayofmydatatype)` (4认同)

小智 52

我使用此方法从对象数组中删除元素.在我的情况下,我的阵列长度很小.因此,如果您有大型阵列,则可能需要其他解决方案.

private int[] RemoveIndices(int[] IndicesArray, int RemoveAt)
{
    int[] newIndicesArray = new int[IndicesArray.Length - 1];

    int i = 0;
    int j = 0;
    while (i < IndicesArray.Length)
    {
        if (i != RemoveAt)
        {
            newIndicesArray[j] = IndicesArray[i];
            j++;
        }

        i++;
    }

    return newIndicesArray;
}
Run Code Online (Sandbox Code Playgroud)

  • 就个人而言,我比接受的答案更喜欢这个答案.它应该同样有效,并且更容易阅读.我可以看一下,知道它是正确的.我必须测试另一个以确保正确写入这些副本. (6认同)

Jon*_*der 45

LINQ单线解决方案:

myArray = myArray.Where((source, index) => index != 1).ToArray();
Run Code Online (Sandbox Code Playgroud)

1在例子是元素的索引,以除去-在这个例子中,每原来的问题,所述第二元件(带1是在基于零的C#数组索引的第二个元素).

一个更完整的例子:

string[] myArray = { "a", "b", "c", "d", "e" };
int indexToRemove = 1;
myArray = myArray.Where((source, index) => index != indexToRemove).ToArray();
Run Code Online (Sandbox Code Playgroud)

运行该代码片段后,其值myArray将为{ "a", "c", "d", "e" }.

  • @Krythic这是一个公平的评论。在紧密的循环中运行数千次,此解决方案的性能不如此页面上其他受好评的解决方案那么好:https://dotnetfiddle.net/z9Xkpn (3认同)
  • 对于需要高性能/频繁访问的区域,不建议使用LINQ。 (2认同)

inf*_*net 9

这是一种删除数组元素的方法,如.Net 3.5,无需复制到另一个数组 - 使用相同的数组实例Array.Resize<T>:

public static void RemoveAt<T>(ref T[] arr, int index)
{
    for (int a = index; a < arr.Length - 1; a++)
    {
        // moving elements downwards, to fill the gap at [index]
        arr[a] = arr[a + 1];
    }
    // finally, let's decrement Array's size by one
    Array.Resize(ref arr, arr.Length - 1);
}
Run Code Online (Sandbox Code Playgroud)

  • “不复制到另一个数组” - 根据链接的文档,Array.Resize 实际上*确实* 在幕后分配了一个新数组,并将元素从旧数组复制到新数组。不过,我喜欢这个解决方案的简洁性。 (3认同)
  • 如果元素的顺序不重要,您可以将索引处的元素与最后一个元素交换,然后调整大小,而不是向下移动所有元素: arr[index] = arr[arr.Length - 1]; Array.Resize(ref arr, arr.Length - 1); (2认同)

Mar*_*own 5

这是我的旧版本,它适用于.NET框架的1.0版本,不需要泛型类型.

public static Array RemoveAt(Array source, int index)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (0 > index || index >= source.Length)
        throw new ArgumentOutOfRangeException("index", index, "index is outside the bounds of source array");

    Array dest = Array.CreateInstance(source.GetType().GetElementType(), source.Length - 1);
    Array.Copy(source, 0, dest, 0, index);
    Array.Copy(source, index + 1, dest, index, source.Length - index - 1);

    return dest;
}
Run Code Online (Sandbox Code Playgroud)

这是这样使用的:

class Program
{
    static void Main(string[] args)
    {
        string[] x = new string[20];
        for (int i = 0; i < x.Length; i++)
            x[i] = (i+1).ToString();

        string[] y = (string[])MyArrayFunctions.RemoveAt(x, 3);

        for (int i = 0; i < y.Length; i++)
            Console.WriteLine(y[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)


naw*_*fal 5

不完全是解决此问题的方法,但如果情况很简单并且您重视时间,则可以对可空类型尝试此方法。

Foos[index] = null
Run Code Online (Sandbox Code Playgroud)

然后检查逻辑中是否有空条目。