C #의 목록에서 항목을 제거하는 방법은 무엇입니까?


191

다음과 같이 결과 목록에 저장된 목록이 있습니다.

var resultlist = results.ToList();

다음과 같이 보입니다 :

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

목록에서 ID 2를 어떻게 제거합니까?

답변:


368

List<T> 사용할 수있는 두 가지 방법이 있습니다.

항목의 색인을 알고 있으면 RemoveAt (int index)를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

resultlist.RemoveAt(1);

또는 Remove (T item)을 사용할 수 있습니다 .

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

49

짧은 답변 :
제거 (목록에서 results)

results.RemoveAll(r => r.ID == 2);ID가 2 인 항목이 results제자리 에 제거됩니다 .

필터 (원본 목록에서 제거하지 않고 results) :

var filtered = result.Where(f => f.ID != 2);ID가 2 인 항목을 제외한 모든 항목을 반환합니다.

자세한 답변 :

나는 생각한다 .RemoveAll()제거하려는 항목 ID 목록을 가질 수 있기 때문에 매우 유연 합니다. 다음 예를 고려하십시오.

당신이 가지고 있다면:

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" },
};

그런 다음 제거 할 ID 목록을 정의 할 수 있습니다.

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 인 Bill이 제거됩니다.


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하는 것입니다.

사실, List의 작업 변경 되고 있다는 점에주의하십시오 . List는 배후에서 배열을 사용하며 필요할 때 더 작거나 더 큰 용량으로 배열을 다시 만들 수 있습니다. 일반적 으로 제거는 기존 배열의 내부 돌연변이입니다.
KeithS

이 스레드 안전하지 않으며, 단순성을 위해 SingleOrDefault를 사용할 수 있으므로 정적 메소드에 포함 할 필요가 없습니다

아무도 스레드 안전하다고 말하지 않았습니다 (스레드가 수행 해야하는 작업에 따라 달라지는 지 여부; 실제로 작업자 스레드에 다른 인 메모리 구성을 제공하는 것이 아니라 동시에 하나의 동시 수집에서 작동하도록하는 것이 바람직 할 수 있음) OP)는 조건 자와 일치하는 레코드를 제외한 모든 레코드를 원 하므로 SingleOrDefault는 실제로 원하지 않는 것을 정확하게 반환합니다 . "정적 방법"은 실제로 대부분의 Linq와 같은 확장 방법이며, 원하지 않는 것 (한 요소 또는 많은 것)이 정의한 것보다 쉽게 ​​정의 할 수있을 때마다 작동합니다.
KeithS

5

다른 접근법이 있습니다. 그것은 사용 List.FindIndex하고 List.RemoveAt.

나는 것이지만 아마도 KeithS 제시 솔루션 (단지 간단한 사용 Where/ ToList그것이에서)이 접근 다릅니다 변이 원래 목록 개체를. 이것은 기대에 따라 좋은 (또는 나쁜) "기능"이 될 수 있습니다.

어쨌든 FindIndex(가드와 결합 된)는 RemoveAtID에 간격이 있거나 순서가 잘못 된 경우 올바른지 확인하고 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

... 또는 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.