Saya memiliki berbagai objek Foo. Bagaimana cara menghapus elemen kedua array?
Saya perlu sesuatu yang mirip RemoveAt()tetapi untuk array reguler.
Saya memiliki berbagai objek Foo. Bagaimana cara menghapus elemen kedua array?
Saya perlu sesuatu yang mirip RemoveAt()tetapi untuk array reguler.
Jawaban:
Jika Anda tidak ingin menggunakan Daftar:
var foos = new List<Foo>(array);
foos.RemoveAt(index);
return foos.ToArray();
Anda dapat mencoba metode ekstensi ini yang belum saya uji:
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;
}
Dan gunakan seperti:
Foo[] bar = GetFoos();
bar = bar.RemoveAt(2);
Sifat array adalah bahwa panjangnya tidak berubah. Anda tidak dapat menambah atau menghapus salah satu item array.
Anda harus membuat array baru yang satu elemen lebih pendek dan menyalin item lama ke array baru, tidak termasuk elemen yang ingin Anda hapus.
Jadi mungkin lebih baik menggunakan Daftar daripada array.
List<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
var myList = myArray.ToList();menggunakan Enumerable.ToList()metode dari System.Linqnamespace.
Saya menggunakan metode ini untuk menghapus elemen dari array objek. Dalam situasi saya, panjang array saya kecil. Jadi jika Anda memiliki array besar Anda mungkin perlu solusi lain.
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;
}
Solusi satu jalur LINQ:
myArray = myArray.Where((source, index) => index != 1).ToArray();
Dalam 1contoh itu adalah indeks elemen yang akan dihapus - dalam contoh ini, per pertanyaan awal, elemen ke-2 (dengan 1menjadi elemen kedua dalam pengindeksan array berbasis C # nol).
Contoh yang lebih lengkap:
string[] myArray = { "a", "b", "c", "d", "e" };
int indexToRemove = 1;
myArray = myArray.Where((source, index) => index != indexToRemove).ToArray();
Setelah menjalankan cuplikan itu, nilai myArrayakan { "a", "c", "d", "e" }.
Ini adalah cara untuk menghapus elemen array, pada .Net 3.5, tanpa menyalin ke array lain - menggunakan contoh array yang sama dengan 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);
}
refsaat Anda memanggil Resizemetode. Panjang instance array adalah tetap dan tidak berubah.
Berikut ini adalah versi lama yang saya miliki yang berfungsi pada versi 1.0 .NET framework dan tidak perlu tipe generik.
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;
}
Ini digunakan seperti ini:
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]);
}
}
Bukan cara yang tepat untuk melakukannya, tetapi jika situasinya sepele dan Anda menghargai waktu Anda, Anda dapat mencoba ini untuk jenis yang dapat dibatalkan.
Foos[index] = null
dan kemudian periksa entri nol dalam logika Anda ..
Seperti biasa, aku terlambat ke pesta ...
Saya ingin menambahkan opsi lain ke daftar solusi bagus yang sudah ada. =)
Saya akan melihat ini sebagai peluang bagus untuk Ekstensi.
Referensi:
http://msdn.microsoft.com/en-us/library/bb311042.aspx
Jadi, kita mendefinisikan beberapa kelas statis dan di dalamnya, Metode kita.
Setelah itu, kita bisa menggunakan metode extended kita mau tak mau. =)
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"
*/
}
}
}
Coba kode di bawah ini:
myArray = myArray.Where(s => (myArray.IndexOf(s) != indexValue)).ToArray();
atau
myArray = myArray.Where(s => (s != "not_this")).ToArray();
Begini cara saya melakukannya ...
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;
}
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;
}
Berikut adalah kumpulan kecil metode pembantu yang saya hasilkan berdasarkan beberapa jawaban yang ada. Ini menggunakan ekstensi dan metode statis dengan parameter referensi untuk idealness maksimum:
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;
}
}
Dari segi kinerja, memang layak, tetapi mungkin bisa ditingkatkan. Removemengandalkan IndexOfdan array baru dibuat untuk setiap elemen yang ingin Anda hapus dengan menelepon RemoveAt.
IndexOfadalah satu-satunya metode ekstensi karena tidak perlu mengembalikan array asli. Newmenerima beberapa elemen dari beberapa tipe untuk menghasilkan array baru dari tipe tersebut. Semua metode lain harus menerima array asli sebagai referensi sehingga tidak perlu menetapkan hasilnya setelah itu terjadi secara internal.
Saya akan mendefinisikan Mergemetode untuk menggabungkan dua array; Namun, itu sudah dapat diselesaikan dengan Addmetode dengan mengirimkan array aktual versus beberapa elemen individual. Oleh karena itu, Adddapat digunakan dalam dua cara berikut untuk bergabung dengan dua set elemen:
Arr.Add<string>(ref myArray, "A", "B", "C");
Atau
Arr.Add<string>(ref myArray, anotherArray);
Saya tahu artikel ini berumur sepuluh tahun dan karena itu mungkin mati, tapi inilah yang saya coba lakukan:
Gunakan metode IEnumerable.Skip (), ditemukan di System.Linq . Ini akan melewati elemen yang dipilih dari array, dan mengembalikan salinan array yang hanya berisi semuanya kecuali objek yang dipilih. Kemudian ulangi saja untuk setiap elemen yang ingin Anda hapus dan setelah itu simpan ke variabel.
Misalnya, jika kita memiliki array bernama "Sampel" (dari tipe int []) dengan 5 angka. Kami ingin menghapus yang ke-2, jadi coba "Sample.Skip (2);" harus mengembalikan array yang sama kecuali tanpa angka ke-2.
Langkah pertama
Anda perlu mengubah array menjadi daftar, Anda bisa menulis metode ekstensi seperti ini
// 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;
}
Langkah kedua
Tulis metode ekstensi untuk mengubah kembali daftar menjadi array
// 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;
}
Langkah-langkah terakhir
Tulis metode terakhir Anda, tetapi ingatlah untuk menghapus elemen pada indeks sebelum mengonversi kembali ke array seperti kode yang ditampilkan
public static string[] removeAt(string[] array, int index) {
List<string> myList = array.ConnvertArrayToList();
myList.RemoveAt(index);
return myList.ConvertListToArray();
}
contoh kode dapat ditemukan di blog saya , terus melacak.
.ToArray()dan List<T>konstruktor yang mengambil urutan yang ada ...
System.Collections.ObjectModel.Collection<Foo>.