ลบรายการออกจากคอลเลกชัน IEnumerable‹T>

ฉันมีคอลเล็กชัน IEnumerable<User> ที่ได้รับความนิยม

ฉันต้องการลบรายการออกจากรายการ ฉันต้องทำอย่างไร?

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

ฉันรู้ว่าคุณไม่ควรลบออกขณะวนซ้ำ ดังนั้นฉันจึงไม่รังเกียจที่จะสร้างคอลเลกชันใหม่หรือลบออกหลังจากนั้น

แต่ฉันไม่รู้วิธีลบสิ่งของ ค่อนข้างจะสูญหายด้วยเหตุผลบางอย่างในเรื่องนี้!

อีกทางเลือกหนึ่งที่ฉันสับสน ฉันจะสร้างคอลเลกชันใหม่เช่น:

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

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

ฉันจะเพิ่มไปยังคอลเลกชันได้อย่างไร?


person loyalflow    schedule 03.01.2013    source แหล่งที่มา


คำตอบ (9)


ไม่ลบ แต่สร้าง List ใหม่โดยไม่มีองค์ประกอบนั้นด้วย 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
คุณกำลังสร้างรายการใหม่ในทั้งสองกรณี ตัวอย่างแรกจะเขียนทับข้อมูลอ้างอิง - person Willem D'Haeseleer; 17.10.2016
comment
คำศัพท์ของคุณไม่ถูกต้อง คุณไม่ได้ลบรายการออกจากรายการ ในทั้งสองตัวอย่าง คุณสร้างรายการใหม่และรายการเก่ายังคงไม่ได้รับผลกระทบ คุณเพียงแต่เขียนทับข้อมูลอ้างอิงในตัวอย่างแรกของคุณ เนื่องจากการระบุว่าผลลัพธ์เป็น remove ไม่ถูกต้อง คุณควรอัปเดตคำถามของคุณเพื่อชี้แจงว่า - person Willem D'Haeseleer; 18.10.2016
comment
เห็นได้ชัดว่าชื่อเรื่องและผู้แต่งต้องการลบรายการ ไม่ใช่สร้างรายการใหม่หากไม่มี... - person Eru; 18.12.2018
comment
แม้ว่าสิ่งนี้จะเป็นประโยชน์สำหรับฉัน แต่ฉันแค่อยากจะชี้ให้เห็นว่าผู้เขียนขอให้ลบรายการออกจาก IEnumerable‹T› ดังนั้นคำต่อท้าย .ToList() ในตัวอย่างจึงไม่จำเป็น (ถึงแม้หลายๆ คนจะเข้ามาติดตามเพจนี้ก็ตาม) - person egmfrs; 13.06.2019
comment
ใช้ AsList() แทน ToList() เสมอ - person Alireza Sattari; 06.03.2021

คุณไม่สามารถลบรายการออกจาก IEnumerable; สามารถระบุได้เท่านั้น ตามที่อธิบายไว้ที่นี่: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

คุณต้องใช้ ICollection หากคุณต้องการเพิ่มและลบรายการ บางทีคุณอาจลองแคสต์ IEnumerable; สิ่งนี้จะใช้งานได้ก็ต่อเมื่อวัตถุต้นแบบใช้ ICollection`

ดูที่นี่สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ ICollection: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx

แน่นอนคุณสามารถสร้างรายการใหม่จาก IEnumerable ของคุณตามที่ lante ชี้ให้เห็น แต่นี่อาจเป็น "การย่อยที่เหมาะสมที่สุด" ขึ้นอยู่กับกรณีการใช้งานจริงของคุณแน่นอน

ICollectionน่าจะเป็นหนทางไป

person Willem D'Haeseleer    schedule 03.01.2013

ลองเปลี่ยน IEnumerable ให้เป็น List จากจุดนี้ไป คุณจะสามารถใช้วิธี List's Remove เพื่อลบรายการต่างๆ ได้

หากต้องการส่งผ่านเป็นพารามิเตอร์ไปยังวิธี Remove โดยใช้ Linq คุณสามารถรับไอเท็มได้โดยวิธีต่อไปนี้:

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

รหัสมีดังนี้:

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
แต่ฉันสามารถกำหนดให้กับสิ่งที่คาดหวังตามมานับไม่ถ้วนได้หรือไม่? ฉันต้องรีสตาร์ทตั้งแต่ต้นเลยไหม? - person loyalflow; 03.01.2013
comment
@ user1361315 แน่นอน List ใช้งาน IEnumerable ดังนั้นคุณจึงสามารถกำหนดให้เป็น IEnumerable ได้ - person dutzu; 03.01.2013

คุณไม่สามารถ. IEnumerable<T> สามารถทำซ้ำได้เท่านั้น

ในตัวอย่างที่สอง คุณสามารถลบออกจากคอลเลกชั่นดั้งเดิมได้โดยการทำซ้ำกับสำเนาของคอลเลกชั่นนั้น

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

คุณสามารถทำสิ่งนี้:

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

users.toList().RemoveAll(user =› ‹เงื่อนไขของคุณ›)

person Jignesh Gothadiya    schedule 23.03.2020

อินเทอร์เฟซ IEnumerable เป็นเพียงแค่นั้น นับได้ - ไม่มีวิธีการใดๆ ให้กับ Add หรือ Remove หรือแก้ไขรายการเลย

อินเทอร์เฟซเพียงจัดเตรียมวิธีการวนซ้ำบางรายการ - การใช้งานส่วนใหญ่ที่จำเป็นต้องมีการแจงนับจะใช้ IEnumerable เช่น List<T>

ทำไมคุณไม่ใช้โค้ดของคุณโดยไม่ใส่รหัสโดยนัยไปที่ 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
ฉันต้องแก้ไขมันแล้วส่งต่อไปยังสิ่งที่คาดหวังนับไม่ถ้วน - person loyalflow; 03.01.2013
comment
จากนั้นแก้ไขและส่งผ่าน - ไม่มีเหตุผลใดที่คุณไม่สามารถส่ง List<T> ไปยังวิธีการที่คาดหวัง IEnumerable<T> เนื่องจาก List<T> มาจาก IEnumerable<T> ฉันไม่คิดว่าคุณจะต้องมีนักแสดงเนื่องจากกฎความแปรปรวนร่วม - person Charleh; 03.01.2013

คุณไม่สามารถลบองค์ประกอบ IEnumerable<T> ได้ แต่คุณสามารถใช้ วิธี Enumerable.Skip

person spajce    schedule 03.01.2013

ขณะนี้มีวิธีส่วนขยายในการแปลง IEnumerable<> เป็น Dictionary<,> ซึ่งจากนั้นจะมีวิธี 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