Untuk permainan saya, saya menggunakan datastruktur "null at index". Pada dasarnya, array dalam (buffer) berukuran statis, dan bukannya menghapus indeks dan mengubah ukuran array, saya hanya membuat indeks nol. Ketika saya perlu menambahkan item, saya hanya menemukan indeks non-nol pertama dan letakkan di sana. Bekerja dengan cukup baik, tetapi jelas tidak untuk semuanya.
Krythic
Jawaban:
202
Jika Anda tidak ingin menggunakan Daftar:
var foos =newList<Foo>(array);
foos.RemoveAt(index);return foos.ToArray();
Anda dapat mencoba metode ekstensi ini yang belum saya uji:
publicstatic 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;}
Contoh pertama yang diberikan dalam jawaban ini jauh lebih efisien daripada yang kedua. Ini membutuhkan dua salinan array dan perubahan segalanya setelah indeks daripada satu salinan array selektif.
Martin Brown
2
+1 tentu saja, tetapi kita juga dapat menggunakan daftar juga ATAU Daftar <Foo> daftar = Daftar baru <Foll> (GetFoos ()); list.Remove (my_foo); list.RemoveAt (2); di mana GetFoos () akan mengembalikan array Foos !!!!
shahjapan
2
Baris pertama di dalam metode harus mengatakan 'source.Length' bukan 'array.Length'.
Nelson
1
Juga, perlu diingat bahwa setiap variabel yang menyimpan referensi ke array asli akan terus berisi data asli dan bahwa setiap perbandingan kesetaraan referensi antara array dalam sumber dan array output akan menghasilkan negatif.
bkqc
1
@ MartinBrown Sebenarnya, mengubah daftar menjadi \ dari dan array jauh lebih lambat daripada salinan array (yang mampu menyalin data pada kecepatan maksimal yang diizinkan oleh CPU dengan hanya beberapa instruksi ASM). Juga, menggeser daftar sangat cepat karena hanya masalah menukar beberapa pointer dan menghapus data node (yang hanya 8 byte [ditambah 16 lainnya untuk head \ tail pointer] dalam kasus ini).
krowe2
66
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.
Ubah array menjadi daftarList<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
Immortal Blue
1
@ImmortalBlue atau hanya var myList = myArray.ToList();menggunakan Enumerable.ToList()metode dari System.Linqnamespace.
Dyndrilliac
58
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.
Secara pribadi, saya suka jawaban ini lebih baik daripada jawaban yang diterima. Seharusnya sama efisiennya, dan lebih mudah dibaca. Saya bisa melihatnya dan tahu itu benar. Saya harus menguji yang lain untuk memastikan salinan itu ditulis dengan benar.
oillio
1
Sayang sekali jawaban ini sangat rendah, padahal jauh lebih baik daripada dua di atasnya.
Sepulchritude
Aaarhg, itulah jawaban yang saya cari! Ini adalah metode terbaik tanpa Daftar.
Jordi Huertas
47
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).
Untuk area yang membutuhkan akses tinggi / kinerja sering, LINQ tidak direkomendasikan.
Krythic
3
@Krythic Itu komentar yang adil. Jalankan ribuan kali dalam satu lingkaran ketat, kinerja solusi ini tidak sebagus beberapa solusi lain yang sangat banyak dipilih pada halaman ini: dotnetfiddle.net/z9Xkpn
Jon Schneider
9
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>:
publicstaticvoidRemoveAt<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 oneArray.Resize(ref arr, arr.Length-1);}
"tanpa menyalin ke array lain" - per dokumentasi terkait, Array.Resize sebenarnya tidak mengalokasikan array baru di belakang layar, dan salinan elemen dari array lama ke yang baru. Tetap saja, saya suka keringkasan solusi ini.
Jon Schneider
Sangat bagus dan jelas jika Anda yakin itu array yang relatif kecil.
Darren
1
Melanjutkan komentar JonSchneider, itu bukan "contoh array yang sama". Itulah mengapa Anda perlu menggunakan refsaat Anda memanggil Resizemetode. Panjang instance array adalah tetap dan tidak berubah.
Jeppe Stig Nielsen
2
Jika urutan elemen tidak penting, alih-alih memindahkan semua elemen ke bawah, Anda dapat menukar elemen pada indeks dengan elemen terakhir dan kemudian mengubah ukuran: arr [index] = arr [arr.Length - 1]; Array.Resize (ref arr, arr.Length - 1);
Bartel
5
Berikut ini adalah versi lama yang saya miliki yang berfungsi pada versi 1.0 .NET framework dan tidak perlu tipe generik.
publicstaticArrayRemoveAt(Array source,int index){if(source ==null)thrownewArgumentNullException("source");if(0> index || index >= source.Length)thrownewArgumentOutOfRangeException("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:
classProgram{staticvoidMain(string[] args){string[] x =newstring[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 ..
publicstaticElementDefinitionImpl[]RemoveElementDefAt(ElementDefinition[] oldList,int removeIndex
){ElementDefinitionImpl[] newElementDefList =newElementDefinitionImpl[ oldList.Length-1];int offset =0;for(int index =0; index < oldList.Length; index++){ElementDefinitionImpl elementDef = oldList[ index ]asElementDefinitionImpl;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;}
Dalam array normal Anda harus mengacak semua entri array di atas 2 dan kemudian mengubah ukurannya menggunakan metode Ubah Ukuran. Anda mungkin lebih baik menggunakan ArrayList.
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:
publicstaticclassArr{publicstaticintIndexOf<TElement>(thisTElement[]Source,TElementElement){for(var i =0; i <Source.Length; i++){if(Source[i].Equals(Element))return i;}return-1;}publicstaticTElement[]Add<TElement>(refTElement[]Source,paramsTElement[]Elements){varOldLength=Source.Length;Array.Resize(refSource,OldLength+Elements.Length);for(int j =0,Count=Elements.Length; j <Count; j++)Source[OldLength+ j]=Elements[j];returnSource;}publicstaticTElement[]New<TElement>(paramsTElement[]Elements){returnElements??newTElement[0];}publicstaticvoidRemove<TElement>(refTElement[]Source,paramsTElement[]Elements){foreach(var i inElements)RemoveAt(refSource,Source.IndexOf(i));}publicstaticvoidRemoveAt<TElement>(refTElement[]Source,intIndex){varResult=newTElement[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:
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.
Tidakkah metode ini hanya mem-bypass sejumlah elemen tertentu dalam suatu urutan dan kemudian mengembalikan elemen yang tersisa ? Dalam contoh Anda, Anda akan "melewati" dua elemen pertama dari daftar generik dan bukan hanya yang kedua!
xnr_z
-4
Langkah pertama
Anda perlu mengubah array menjadi daftar, Anda bisa menulis metode ekstensi seperti ini
// Convert An array of string to a list of stringpublicstaticList<string>ConnvertArrayToList(thisstring[]array){// DECLARE a list of string and add all element of the array into itList<string> myList =newList<string>();foreach(string s inarray){
myList.Add(s);}return myList;}
Langkah kedua
Tulis metode ekstensi untuk mengubah kembali daftar menjadi array
// convert a list of string to an array publicstaticstring[]ConvertListToArray(thisList<string>list){string[]array=newstring[list.Capacity];array=list.Select(i => i.ToString()).ToArray();returnarray;}
Langkah-langkah terakhir
Tulis metode terakhir Anda, tetapi ingatlah untuk menghapus elemen pada indeks sebelum mengonversi kembali ke array seperti kode yang ditampilkan
System.Collections.ObjectModel.Collection<Foo>
.Jawaban:
Jika Anda tidak ingin menggunakan Daftar:
Anda dapat mencoba metode ekstensi ini yang belum saya uji:
Dan gunakan seperti:
sumber
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.
sumber
List<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
var myList = myArray.ToList();
menggunakanEnumerable.ToList()
metode dariSystem.Linq
namespace.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.
sumber
Solusi satu jalur LINQ:
Dalam
1
contoh itu adalah indeks elemen yang akan dihapus - dalam contoh ini, per pertanyaan awal, elemen ke-2 (dengan1
menjadi elemen kedua dalam pengindeksan array berbasis C # nol).Contoh yang lebih lengkap:
Setelah menjalankan cuplikan itu, nilai
myArray
akan{ "a", "c", "d", "e" }
.sumber
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>
:sumber
ref
saat Anda memanggilResize
metode. 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.
Ini digunakan seperti ini:
sumber
Bukan cara yang tepat untuk melakukannya, tetapi jika situasinya sepele dan Anda menghargai waktu Anda, Anda dapat mencoba ini untuk jenis yang dapat dibatalkan.
dan kemudian periksa entri nol dalam logika Anda ..
sumber
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. =)
sumber
Coba kode di bawah ini:
atau
sumber
Begini cara saya melakukannya ...
sumber
Dalam array normal Anda harus mengacak semua entri array di atas 2 dan kemudian mengubah ukurannya menggunakan metode Ubah Ukuran. Anda mungkin lebih baik menggunakan ArrayList.
sumber
sumber
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:
Dari segi kinerja, memang layak, tetapi mungkin bisa ditingkatkan.
Remove
mengandalkanIndexOf
dan array baru dibuat untuk setiap elemen yang ingin Anda hapus dengan meneleponRemoveAt
.IndexOf
adalah satu-satunya metode ekstensi karena tidak perlu mengembalikan array asli.New
menerima 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
Merge
metode untuk menggabungkan dua array; Namun, itu sudah dapat diselesaikan denganAdd
metode dengan mengirimkan array aktual versus beberapa elemen individual. Oleh karena itu,Add
dapat digunakan dalam dua cara berikut untuk bergabung dengan dua set elemen:Atau
sumber
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.
sumber
Langkah pertama
Anda perlu mengubah array menjadi daftar, Anda bisa menulis metode ekstensi seperti ini
Langkah kedua
Tulis metode ekstensi untuk mengubah kembali daftar menjadi array
Langkah-langkah terakhir
Tulis metode terakhir Anda, tetapi ingatlah untuk menghapus elemen pada indeks sebelum mengonversi kembali ke array seperti kode yang ditampilkan
contoh kode dapat ditemukan di blog saya , terus melacak.
sumber
.ToArray()
danList<T>
konstruktor yang mengambil urutan yang ada ...