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

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

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

Ответы [ 14 ]

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

Вот как я это сделал ...

    public static ElementDefinitionImpl[] RemoveElementDefAt(
        ElementDefinition[] oldList,
        int removeIndex
    )
    {
        ElementDefinitionImpl[] newElementDefList = new ElementDefinitionImpl[ oldList.Length - 1 ];

        int offset = 0;
        for ( int index = 0; index < oldList.Length; index++ )
        {
            ElementDefinitionImpl elementDef = oldList[ index ] as ElementDefinitionImpl;
            if ( index == removeIndex )
            {
                //  This is the one we want to remove, so we won't copy it.  But 
                //  every subsequent elementDef will by shifted down by one.
                offset = -1;
            }
            else
            {
                newElementDefList[ index + offset ] = elementDef;
            }
        }
        return newElementDefList;
    }
0 голосов
/ 06 февраля 2019

Я знаю, что этой статье десять лет, и поэтому она, вероятно, мертва, но вот что я попробую сделать:

Используйте метод IEnumerable.Skip (), найденный в System.Linq . Он пропустит выбранный элемент из массива и вернет другую копию массива, которая содержит только все, кроме выбранного объекта. Затем просто повторите это для каждого элемента, который вы хотите удалить, и после этого сохраните его в переменной.

Например, если у нас есть массив с именем «Sample» (типа int []) с 5 числами. Мы хотим удалить 2-й, поэтому пробуем "Sample.Skip (2);" должен возвращать тот же массив, кроме как без 2-го числа.

0 голосов
/ 23 апреля 2017

Вот небольшая коллекция вспомогательных методов, которые я создал на основе некоторых из существующих ответов. Он использует как расширения, так и статические методы с опорными параметрами для максимальной идеальности:

public static class Arr
{
    public static int IndexOf<TElement>(this TElement[] Source, TElement Element)
    {
        for (var i = 0; i < Source.Length; i++)
        {
            if (Source[i].Equals(Element))
                return i;
        }

        return -1;
    }

    public static TElement[] Add<TElement>(ref TElement[] Source, params TElement[] Elements)
    {
        var OldLength = Source.Length;
        Array.Resize(ref Source, OldLength + Elements.Length);

        for (int j = 0, Count = Elements.Length; j < Count; j++)
            Source[OldLength + j] = Elements[j];

        return Source;
    }

    public static TElement[] New<TElement>(params TElement[] Elements)
    {
        return Elements ?? new TElement[0];
    }

    public static void Remove<TElement>(ref TElement[] Source, params TElement[] Elements)
    {
        foreach (var i in Elements)
            RemoveAt(ref Source, Source.IndexOf(i));
    }

    public static void RemoveAt<TElement>(ref TElement[] Source, int Index)
    {
        var Result = new TElement[Source.Length - 1];

        if (Index > 0)
            Array.Copy(Source, 0, Result, 0, Index);

        if (Index < Source.Length - 1)
            Array.Copy(Source, Index + 1, Result, Index, Source.Length - Index - 1);

        Source = Result;
    }
}

Производительность мудрая, она приличная, но, вероятно, ее можно улучшить. Remove опирается на IndexOf, и для каждого элемента, который вы хотите удалить, создается новый массив, вызывая RemoveAt.

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

Я бы определил Merge метод для объединения двух массивов; однако это уже может быть достигнуто с помощью метода Add путем передачи фактического массива вместо нескольких отдельных элементов. Следовательно, Add может использоваться следующими двумя способами для объединения двух наборов элементов:

Arr.Add<string>(ref myArray, "A", "B", "C");

или

Arr.Add<string>(ref myArray, anotherArray);
0 голосов
/ 17 апреля 2012

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

// Convert An array of string  to a list of string
public static List<string> ConnvertArrayToList(this string [] array) {

    // DECLARE a list of string and add all element of the array into it

    List<string> myList = new List<string>();
    foreach( string s in array){
        myList.Add(s);
    }
    return myList;
} 

Второй шаг
Напишите метод расширения для преобразования списка обратно в массив

// convert a list of string to an array 
public static string[] ConvertListToArray(this List<string> list) {

    string[] array = new string[list.Capacity];
    array = list.Select(i => i.ToString()).ToArray();
    return array;
}

Последние шаги
Напишите свой последний метод, но не забудьте удалить элемент по индексу перед преобразованием обратно в массив, как показано в коде

public static string[] removeAt(string[] array, int index) {

    List<string> myList = array.ConnvertArrayToList();
    myList.RemoveAt(index);
    return myList.ConvertListToArray();
} 

примеры кодов можно найти на моем блоге , продолжайте отслеживать.

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