다음과 같은 LINQ 쿼리가 있다고 가정하십시오.
var authors = from x in authorsList
where x.firstname == "Bob"
select x;
그것이 authorsList
유형 이라면, 쿼리에 의해 반환 된 요소를 List<Author>
어떻게 삭제할 수 있습니까?Author
authorsList
authors
또는 다른 방법으로, 이름의 동일한 Bob을 모두에서 어떻게 삭제할 수 authorsList
있습니까?
참고 : 이것은 질문의 목적을 위해 단순화 된 예입니다.
답변
글쎄, 처음에 그것들을 배제하는 것이 더 쉬울 것입니다 :
authorsList = authorsList.Where(x => x.FirstName != "Bob").ToList();
그러나 authorsList
이전 컬렉션에서 작성자를 제거하는 대신 값을 변경하면 됩니다. 또는 다음을 사용할 수 있습니다 RemoveAll
.
authorsList.RemoveAll(x => x.FirstName == "Bob");
다른 컬렉션을 기반으로 해야하는 경우 HashSet, RemoveAll 및 Contains를 사용합니다.
var setToRemove = new HashSet<Author>(authors);
authorsList.RemoveAll(x => setToRemove.Contains(x));
답변
이를 위해서는 List <T> .RemoveAll 을 사용하는 것이 좋습니다 .
authorsList.RemoveAll((x) => x.firstname == "Bob");
답변
실제로 항목을 제거 해야하는 경우 Except ()는 어떻습니까?
Linq를 중첩하여 새 목록을 기준으로 제거하거나 즉석에서 제거 할 수 있습니다.
var authorsList = new List<Author>()
{
new Author{ Firstname = "Bob", Lastname = "Smith" },
new Author{ Firstname = "Fred", Lastname = "Jones" },
new Author{ Firstname = "Brian", Lastname = "Brains" },
new Author{ Firstname = "Billy", Lastname = "TheKid" }
};
var authors = authorsList.Where(a => a.Firstname == "Bob");
authorsList = authorsList.Except(authors).ToList();
authorsList = authorsList.Except(authorsList.Where(a=>a.Firstname=="Billy")).ToList();
답변
LINQ는 업데이트 지원이 아닌 쿼리를 제공하므로 표준 LINQ 연산자로는이 작업을 수행 할 수 없습니다.
그러나 새 목록을 생성하고 이전 목록을 바꿀 수 있습니다.
var authorsList = GetAuthorList();
authorsList = authorsList.Where(a => a.FirstName != "Bob").ToList();
또는 authors
두 번째 단계에서 모든 항목을 제거 할 수 있습니다.
var authorsList = GetAuthorList();
var authors = authorsList.Where(a => a.FirstName == "Bob").ToList();
foreach (var author in authors)
{
authorList.Remove(author);
}
답변
간단한 해결책 :
static void Main()
{
List<string> myList = new List<string> { "Jason", "Bob", "Frank", "Bob" };
myList.RemoveAll(x => x == "Bob");
foreach (string s in myList)
{
//
}
}
답변
RemoveAll
와 사용하는 사람 Except
과 사용하는 사람 사이에 차이가 있는지 궁금 하여 HashSet
빠른 성능 검사를 수행했습니다. 🙂
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace ListRemoveTest
{
class Program
{
private static Random random = new Random( (int)DateTime.Now.Ticks );
static void Main( string[] args )
{
Console.WriteLine( "Be patient, generating data..." );
List<string> list = new List<string>();
List<string> toRemove = new List<string>();
for( int x=0; x < 1000000; x++ )
{
string randString = RandomString( random.Next( 100 ) );
list.Add( randString );
if( random.Next( 1000 ) == 0 )
toRemove.Insert( 0, randString );
}
List<string> l1 = new List<string>( list );
List<string> l2 = new List<string>( list );
List<string> l3 = new List<string>( list );
List<string> l4 = new List<string>( list );
Console.WriteLine( "Be patient, testing..." );
Stopwatch sw1 = Stopwatch.StartNew();
l1.RemoveAll( toRemove.Contains );
sw1.Stop();
Stopwatch sw2 = Stopwatch.StartNew();
l2.RemoveAll( new HashSet<string>( toRemove ).Contains );
sw2.Stop();
Stopwatch sw3 = Stopwatch.StartNew();
l3 = l3.Except( toRemove ).ToList();
sw3.Stop();
Stopwatch sw4 = Stopwatch.StartNew();
l4 = l4.Except( new HashSet<string>( toRemove ) ).ToList();
sw3.Stop();
Console.WriteLine( "L1.Len = {0}, Time taken: {1}ms", l1.Count, sw1.Elapsed.TotalMilliseconds );
Console.WriteLine( "L2.Len = {0}, Time taken: {1}ms", l1.Count, sw2.Elapsed.TotalMilliseconds );
Console.WriteLine( "L3.Len = {0}, Time taken: {1}ms", l1.Count, sw3.Elapsed.TotalMilliseconds );
Console.WriteLine( "L4.Len = {0}, Time taken: {1}ms", l1.Count, sw3.Elapsed.TotalMilliseconds );
Console.ReadKey();
}
private static string RandomString( int size )
{
StringBuilder builder = new StringBuilder();
char ch;
for( int i = 0; i < size; i++ )
{
ch = Convert.ToChar( Convert.ToInt32( Math.Floor( 26 * random.NextDouble() + 65 ) ) );
builder.Append( ch );
}
return builder.ToString();
}
}
}
아래 결과 :
Be patient, generating data...
Be patient, testing...
L1.Len = 985263, Time taken: 13411.8648ms
L2.Len = 985263, Time taken: 76.4042ms
L3.Len = 985263, Time taken: 340.6933ms
L4.Len = 985263, Time taken: 340.6933ms
우리가 볼 수 있듯이, 그 경우 가장 좋은 옵션은 RemoveAll(HashSet)
답변
이것은 매우 오래된 질문이지만이 작업을 수행하는 간단한 방법을 찾았습니다.
authorsList = authorsList.Except(authors).ToList();
반환 변수 authorsList
는 a List<T>
이므로로 IEnumerable<T>
반환되는 변수 는 Except()
로 변환되어야합니다 List<T>
.