วิธีลบรายการออกจากรายการใน C #


192

ฉันมีรายการที่เก็บไว้ในรายการผลลัพธ์ดังนี้:

var resultlist = results.ToList();

ดูเหมือนว่า:

ID FirstName  LastName
-- ---------  --------
1  Bill       Smith
2  John       Wilson
3  Doug       Berg

ฉันจะลบ ID 2 ออกจากรายการได้อย่างไร

คำตอบ:


368

List<T> มีสองวิธีที่คุณสามารถใช้ได้

RemoveAt (ดัชนี int)สามารถใช้ถ้าคุณรู้ว่าดัชนีของรายการ ตัวอย่างเช่น:

resultlist.RemoveAt(1);

หรือคุณสามารถใช้ลบ (รายการ T) :

var itemToRemove = resultlist.Single(r => r.Id == 2);
resultList.Remove(itemToRemove);

เมื่อคุณไม่แน่ใจว่ารายการที่มีอยู่จริงๆคุณสามารถใช้SingleOrDefault SingleOrDefaultจะส่งคืนnullหากไม่มีรายการ ( Singleจะส่งข้อยกเว้นเมื่อไม่พบรายการ) ทั้งสองจะโยนเมื่อมีค่าซ้ำกัน (สองรายการด้วยเหมือนกันid)

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2);
if (itemToRemove != null)
    resultList.Remove(itemToRemove);

5
ดีกว่าบางทีvar itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);
Vlad

1
สิ่งนี้ไม่ควรเป็นresultlist.Items.RemoveAt(1);หรือ
DreamTeK

50

คำตอบสั้น ๆ :
ลบ (จากรายการresults)

results.RemoveAll(r => r.ID == 2);จะลบรายการที่มีID 2ในresults(ในตำแหน่ง)

ตัวกรอง (โดยไม่ลบออกจากรายการเดิมresults):

var filtered = result.Where(f => f.ID != 2);ส่งคืนรายการทั้งหมดยกเว้นรายการที่มีID 2

คำตอบโดยละเอียด:

ฉันคิดว่า.RemoveAll()มีความยืดหยุ่นมากเพราะคุณสามารถมีรายการรหัสรายการที่คุณต้องการลบ - โปรดดูตัวอย่างต่อไปนี้

ถ้าคุณมี:

class myClass {
    public int ID; public string FirstName; public string LastName;
}

และกำหนดค่าบางอย่างให้resultsกับ:

var results=new List<myClass> {
    new myClass()  { ID=1, FirstName="Bill", LastName="Smith" },
    new myClass()  { ID=2, FirstName="John", LastName="Wilson" },
    new myClass()  { ID=3, FirstName="Doug", LastName="Berg" },
    new myClass()  { ID=4, FirstName="Bill", LastName="Wilson" },
};

จากนั้นคุณสามารถกำหนดรายการรหัสที่จะลบ:

var removeList = new List<int>() { 2, 3 };

และใช้สิ่งนี้เพื่อลบ:

results.RemoveAll(r => removeList.Any(a => a==r.ID));

มันจะเอารายการที่ 2 และ 3และเก็บรายการที่ 1 และ 4 - removeListตามที่ระบุโดย โปรดทราบว่าสิ่งนี้เกิดขึ้นดังนั้นจึงไม่จำเป็นต้องมีการเลือกเพิ่มเติม

แน่นอนคุณยังสามารถใช้กับรายการเดียวเช่น:

results.RemoveAll(r => r.ID==4);

ที่จะลบบิลกับ ID 4 ในตัวอย่างของเรา


DotNetFiddle: เรียกใช้การสาธิต


45
resultList = results.Where(x=>x.Id != 2).ToList();

มีผู้ช่วย Linq เล็กน้อยที่ฉันชอบที่ใช้งานง่ายและสามารถสืบค้นด้วยเงื่อนไข "ที่ไม่" อ่านง่ายขึ้นเล็กน้อย:

public static IEnumerable<T> ExceptWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
    return source.Where(x=>!predicate(x));
}

//usage in above situation
resultList = results.ExceptWhere(x=>x.Id == 2).ToList();

1
อีกวิธีที่คล้ายกัน (ที่ใช้เพรดิเคต) คือการใช้List.FindIndex/ List.RemoteAt(ซึ่งมีคุณสมบัติ "ดี" หรือ "ไม่ดีมาก" ของการดำเนินการกลายพันธุ์)

จริง แต่ต้องระวังเกี่ยวกับการบอกว่าการดำเนินการของรายการกำลังกลายพันธุ์ รายการใช้อาเรย์หลังฉากและสามารถสร้างอาเรย์ด้วยความจุที่น้อยลงหรือใหญ่ขึ้นเมื่อคิดว่าจำเป็น โดยปกติแล้วการลบคือการกลายพันธุ์ในสถานที่ของอาร์เรย์ที่มีอยู่
KeithS

นี่ไม่ใช่เธรดที่ปลอดภัยและเพื่อความง่ายคุณสามารถใช้ SingleOrDefault ได้โดยไม่จำเป็นต้องมีวิธีการแบบคงที่

ไม่มีใครบอกว่ามันปลอดภัยสำหรับเธรด (และไม่ว่ามันจะขึ้นอยู่กับว่าเธรดควรจะทำอะไรในความเป็นจริงมันอาจจะดีกว่าที่จะให้โครงสร้างหน่วยความจำในหน่วยความจำที่แตกต่างกับเธรดของผู้ปฏิบัติงาน ) และ OP ต้องการบันทึกทั้งหมดยกเว้นหนึ่งรายการที่ตรงกับภาคแสดงดังนั้น SingleOrDefault จะส่งคืนสิ่งที่พวกเขาไม่ต้องการ "วิธีการแบบคงที่" ในความเป็นจริงแล้วเป็นวิธีการขยายเช่นเดียวกับส่วนใหญ่ของ Linq และมันทำงานเมื่อใดก็ตามที่คุณไม่ต้องการ (องค์ประกอบหนึ่งหรือหลายคน) ง่ายต่อการกำหนดกว่าที่คุณทำ
KeithS

5

มีวิธีการอื่น มันใช้และList.FindIndexList.RemoveAt

ในขณะที่ฉันอาจจะใช้วิธีแก้ปัญหาที่นำเสนอโดย KeithS (เพียงแค่ง่าย ๆWhere/ ToList) วิธีนี้แตกต่างกันในการที่มันกลายพันธุ์วัตถุรายการเดิม นี่อาจเป็น "คุณสมบัติ" ที่ดี (หรือไม่ดี) ขึ้นอยู่กับความคาดหวัง

ไม่ว่าในกรณีใด ๆFindIndex(ควบคู่กับยาม) รับรองว่าRemoveAtจะถูกต้องหากมีช่องว่างในรหัสหรือการสั่งซื้อผิด ฯลฯ และการใช้RemoveAt(vs Remove) หลีกเลี่ยงการค้นหาO (n) ครั้งที่สองผ่านรายการ

นี่เป็นตัวอย่างของLINQPad :

var list = new List<int> { 1, 3, 2 };
var index = list.FindIndex(i => i == 2); // like Where/Single
if (index >= 0) {   // ensure item found
    list.RemoveAt(index);
}
list.Dump();        // results -> 1, 3

การเข้ารหัสที่มีความสุข


4

คุณไม่ได้ระบุชนิดของรายการ แต่รายการทั่วไปสามารถใช้RemoveAt(index)วิธีการหรือRemove(obj)วิธีการ:

// Remove(obj)
var item = resultList.Single(x => x.Id == 2);
resultList.Remove(item);

// RemoveAt(index)
resultList.RemoveAt(1);



0
{
    class Program
    {
        public static List<Product> list;
        static void Main(string[] args)
        {

            list = new List<Product>() { new Product() { ProductId=1, Name="Nike 12N0",Brand="Nike",Price=12000,Quantity=50},
                 new Product() { ProductId =2, Name = "Puma 560K", Brand = "Puma", Price = 120000, Quantity = 55 },
                 new Product() { ProductId=3, Name="WoodLand V2",Brand="WoodLand",Price=21020,Quantity=25},
                 new Product() { ProductId=4, Name="Adidas S52",Brand="Adidas",Price=20000,Quantity=35},
                 new Product() { ProductId=5, Name="Rebook SPEED2O",Brand="Rebook",Price=1200,Quantity=15}};


            Console.WriteLine("Enter ProductID to remove");
            int uno = Convert.ToInt32(Console.ReadLine());
            var itemToRemove = list.Find(r => r.ProductId == uno);
            if (itemToRemove != null)
                list.Remove(itemToRemove);
            Console.WriteLine($"{itemToRemove.ProductId}{itemToRemove.Name}{itemToRemove.Brand}{itemToRemove.Price}{ itemToRemove.Quantity}");
            Console.WriteLine("------------sucessfully Removed---------------");

            var query2 = from x in list select x;
            foreach (var item in query2)
            {
                /*Console.WriteLine(item.ProductId+" "+item.Name+" "+item.Brand+" "+item.Price+" "+item.Quantity );*/
                Console.WriteLine($"{item.ProductId}{item.Name}{item.Brand}{item.Price}{ item.Quantity}");
            }

        }

    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.