Hapus item dari koleksi IEnumerable‹T›

Saya memiliki koleksi IEnumerable<User> yang terisi.

Saya ingin menghapus item darinya, bagaimana caranya?

foreach(var u in users)
{
  if(u.userId = 1123)
  {
    // remove!
  }
}

Saya tahu Anda tidak seharusnya menghapus saat mengulang, jadi saya tidak keberatan membuat koleksi baru atau menghapusnya setelahnya.

Tapi saya tidak tahu cara menghapus item, agak hilang karena alasan tertentu!

Alternatifnya yang saya juga bingung, bagaimana cara membuat koleksi baru seperti:

IEnumerable<User> modifiedUsers = new List<User>();

foreach(var u in users)
{
   if(u.userId != 1233)
   {
        modifiedUsers.add ??????
   }
}

Bagaimana cara menambah koleksi?


person loyalflow    schedule 03.01.2013    source sumber


Jawaban (9)


Bukan menghapus tetapi membuat List baru tanpa elemen itu dengan LINQ:

// remove
users = users.Where(u => u.userId != 123).ToList();

// new list
var modified = users.Where(u => u.userId == 123).ToList();
person lante    schedule 03.01.2013
comment
Anda membuat daftar baru dalam kedua kasus tersebut. Contoh pertama hanya menimpa referensi. - person Willem D'Haeseleer; 17.10.2016
comment
Terminologi Anda tidak benar. Anda tidak menghapus item dari daftar, Dalam kedua contoh Anda membuat daftar baru dan daftar lama tetap tidak terpengaruh. Anda hanya menimpa referensi pada contoh pertama Anda, sehingga menyatakan bahwa hasilnya adalah remove salah. Anda harus memperbarui pertanyaan Anda untuk memperjelasnya. - person Willem D'Haeseleer; 18.10.2016
comment
Yang jelas judul dan penulisnya ingin MENGHAPUS item tersebut, bukan membuat daftar baru tanpanya... - person Eru; 18.12.2018
comment
Meskipun ini berguna bagi saya, saya hanya ingin menunjukkan bahwa Penulis meminta untuk menghapus item dari IEnumerable‹T› , oleh karena itu akhiran .ToList() dalam contoh tidak diperlukan. (Meskipun mungkin itulah yang diinginkan banyak orang yang membuka halaman ini.) - person egmfrs; 13.06.2019
comment
Selalu gunakan AsList() daripada ToList() - person Alireza Sattari; 06.03.2021

Anda tidak dapat menghapus item dari IEnumerable; itu hanya dapat dihitung, seperti dijelaskan di sini: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

Anda harus menggunakan ICollection jika ingin menambah dan menghapus item. Mungkin Anda dapat mencoba dan mentransmisikan IEnumerable; ini tentu saja hanya akan berfungsi jika objek yang mendasarinya mengimplementasikan ICollection`.

Lihat di sini untuk informasi lebih lanjut tentang ICollection: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx

Anda tentu saja dapat membuat daftar baru dari IEnumerable Anda, seperti yang ditunjukkan oleh lante, tetapi ini mungkin "kurang optimal", tentu saja tergantung pada kasus penggunaan Anda yang sebenarnya.

ICollection mungkin adalah cara yang tepat.

person Willem D'Haeseleer    schedule 03.01.2013

Coba ubah IEnumerable menjadi List. Mulai saat ini Anda akan dapat menggunakan metode Remove List untuk menghapus item.

Untuk meneruskannya sebagai param ke metode Remove menggunakan Linq Anda bisa mendapatkan item dengan metode berikut:

  • users.Single(x => x.userId == 1123)
  • users.First(x => x.userId == 1123)

Kodenya adalah sebagai berikut:

users = users.ToList(); // Get IEnumerable as List

users.Remove(users.First(x => x.userId == 1123)); // Remove item

// Finished
person dutzu    schedule 03.01.2013
comment
tetapi bisakah saya menugaskannya ke sesuatu yang memerlukan kata penutup yang tak terhitung jumlahnya? apakah saya harus mengulanginya lagi dari awal? - person loyalflow; 03.01.2013
comment
@ user1361315 tentu saja, Daftar mengimplementasikan IEnumerable, jadi Anda memang bisa memasukkannya ke IEnumerable - person dutzu; 03.01.2013

Anda tidak bisa. IEnumerable<T> hanya dapat diulang.

Dalam contoh kedua, Anda dapat menghapus dari koleksi asli dengan mengulangi salinannya

foreach(var u in users.ToArray()) // ToArray creates a copy
{
   if(u.userId != 1233)
   {
        users.Remove(u);
   }
}
person Tilak    schedule 03.01.2013

Anda dapat melakukan sesuatu seperti ini:

users = users.Where(x => x.userId != userIdToRemove);
person Rafael Mori    schedule 29.01.2020

pengguna.toList().RemoveAll(pengguna =› ‹kondisi Anda›)

person Jignesh Gothadiya    schedule 23.03.2020

Antarmuka IEnumerable hanya itu, dapat dihitung - tidak menyediakan metode apa pun untuk Add atau Remove atau mengubah daftar sama sekali.

Antarmuka hanya menyediakan cara untuk mengulangi beberapa item - sebagian besar implementasi yang memerlukan enumerasi akan mengimplementasikan IEnumerable seperti List<T>

Mengapa Anda tidak menggunakan kode Anda saja tanpa pemeran implisit ke IEnumerable

// Treat this like a list, not an enumerable
List<User> modifiedUsers = new List<User>();

foreach(var u in users)
{
   if(u.userId != 1233)
   {
        // Use List<T>.Add
        modifiedUsers.Add(u);
   }
}
person Charleh    schedule 03.01.2013
comment
Saya harus memodifikasinya, lalu meneruskannya ke sesuatu yang mengharapkan banyak hal. - person loyalflow; 03.01.2013
comment
Kemudian modifikasi dan teruskan - tidak ada alasan Anda tidak dapat meneruskan List<T> ke metode yang mengharapkan IEnumerable<T> karena List<T> berasal dari IEnumerable<T>. Saya bahkan berpikir Anda tidak memerlukan pemeran karena aturan kovarians. - person Charleh; 03.01.2013

Anda tidak dapat menghapus elemen IEnumerable<T>, namun Anda dapat menggunakan Metode Enumerable.Skip

person spajce    schedule 03.01.2013

Sekarang ada metode ekstensi untuk mengubah IEnumerable<> menjadi Dictionary<,> yang kemudian memiliki metode Remove.

public readonly IEnumerable<User> Users = new User[]; // or however this would be initialized

// To take an item out of the collection
Users.ToDictionary(u => u.Id).Remove(1123);

// To take add an item to the collection
Users.ToList().Add(newuser);
person drovani    schedule 31.01.2019