我有一个 Foo 对象的数组。如何删除这个数组的第二个元素?
我需要类似于 RemoveAt()
但适用于普通数组的方法。
这是我的做法...
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;
}
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);
我知道这篇文章已经十年了,可能已经过时了,但是这是我会尝试做的:
使用IEnumerable.Skip()方法,它在System.Linq中找到。它将跳过数组中选择的元素,并返回另一个仅包含除所选对象以外的所有内容的数组副本。然后只需为要删除的每个元素重复此操作,然后将其保存到变量中。
例如,如果我们有一个名为“Sample”的数组(类型为int []),其中包含5个数字。我们想要删除第二个数字,因此尝试“Sample.Skip(2);”应该返回相同的数组,但不包括第二个数字。
第一步
您需要将数组转换为列表,您可以编写一个扩展方法,如下所示:
// 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();
}
示例代码可以在我的博客上找到,请持续关注。
.ToArray()
和List<T>
构造函数可以接受现有序列,这种做法有些不太理智。 - user7116
System.Collections.ObjectModel.Collection<Foo>
。 - abatishchev