Удалить элемент обычного массива - PullRequest
114 голосов
/ 19 января 2009

У меня есть массив объектов Foo. Как мне удалить второй элемент массива?

Мне нужно что-то похожее на RemoveAt(), но для обычного массива.

Ответы [ 14 ]

170 голосов
/ 19 января 2009

Если вы не хотите использовать Список:

var foos = new List<Foo>(array);
foos.RemoveAt(index);
return foos.ToArray();

Вы можете попробовать этот метод расширения, который я на самом деле не тестировал:

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

И используйте это как:

Foo[] bar = GetFoos();
bar = bar.RemoveAt(2);
61 голосов
/ 19 января 2009

Природа массивов такова, что их длина неизменна. Вы не можете добавлять или удалять любые элементы массива.

Вам нужно будет создать новый массив на один элемент короче и скопировать старые элементы в новый массив, исключая элемент, который вы хотите удалить.

Так что, вероятно, лучше использовать List вместо массива.

49 голосов
/ 12 декабря 2010

Я использую этот метод для удаления элемента из массива объектов. В моей ситуации мои массивы имеют небольшую длину. Поэтому, если у вас большие массивы, вам может понадобиться другое решение.

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;
}
44 голосов
/ 11 сентября 2014

LINQ однострочное решение:

myArray = myArray.Where((source, index) => index != 1).ToArray();

1 в этом примере - это индекс удаляемого элемента - в этом примере, согласно исходному вопросу, 2-й элемент (с 1, являющимся вторым элементом в индексации массива на основе нуля в C #).

Более полный пример:

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

После запуска этого фрагмента значение myArray будет { "a", "c", "d", "e" }.

9 голосов
/ 24 июля 2013

Это способ удалить элемент массива, начиная с .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);
}
5 голосов
/ 19 января 2009

Вот моя старая версия, которая работает на версии 1.0 фреймворка .NET и не требует универсальных типов.

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

Это используется так:

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]);
    }
}
3 голосов
/ 08 октября 2011

Не совсем так, но если ситуация тривиальна, и вы цените свое время, вы можете попробовать это для обнуляемых типов.

Foos[index] = null

и позже проверьте наличие нулевых записей в вашей логике.

2 голосов
/ 02 января 2014

Как обычно, я опаздываю на вечеринку ...

Я бы хотел добавить еще одну опцию в список уже существующих хороших решений. =)
Я бы посчитал это хорошей возможностью для расширений.

Ссылка: http://msdn.microsoft.com/en-us/library/bb311042.aspx

Итак, мы определяем некоторый статический класс и в нем наш Метод.
После этого мы можем использовать наш расширенный метод волей-неволей. =)

using System;

namespace FunctionTesting {

    // The class doesn't matter, as long as it's static
    public static class SomeRandomClassWhoseNameDoesntMatter {

        // Here's the actual method that extends arrays
        public static T[] RemoveAt<T>( this T[] oArray, int idx ) {
            T[] nArray = new T[oArray.Length - 1];
            for( int i = 0; i < nArray.Length; ++i ) {
                nArray[i] = ( i < idx ) ? oArray[i] : oArray[i + 1];
            }
            return nArray;
        }
    }

    // Sample usage...
    class Program {
        static void Main( string[] args ) {
            string[] myStrArray = { "Zero", "One", "Two", "Three" };
            Console.WriteLine( String.Join( " ", myStrArray ) );
            myStrArray = myStrArray.RemoveAt( 2 );
            Console.WriteLine( String.Join( " ", myStrArray ) );
            /* Output
             * "Zero One Two Three"
             * "Zero One Three"
             */

            int[] myIntArray = { 0, 1, 2, 3 };
            Console.WriteLine( String.Join( " ", myIntArray ) );
            myIntArray = myIntArray.RemoveAt( 2 );
            Console.WriteLine( String.Join( " ", myIntArray ) );
            /* Output
             * "0 1 2 3"
             * "0 1 3"
             */
        }
    }
}
1 голос
/ 22 июня 2015
    private int[] removeFromArray(int[] array, int id)
    {
        int difference = 0, currentValue=0;
        //get new Array length
        for (int i=0; i<array.Length; i++)
        {
            if (array[i]==id)
            {
                difference += 1;
            }
        }
        //create new array
        int[] newArray = new int[array.Length-difference];
        for (int i = 0; i < array.Length; i++ )
        {
            if (array[i] != id)
            {
                newArray[currentValue] = array[i];
                currentValue += 1;
            }
        }

        return newArray;
    }
1 голос
/ 19 января 2009

В обычном массиве вы должны перемешать все элементы массива выше 2, а затем изменить его размер, используя метод Resize. Возможно, вам лучше использовать ArrayList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...