LINQ를 사용하여 목록에서 요소 제거
다음과 같은 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
인 List<T>
의 IEnumerable<T>
에 의해 반환이 Except()
A를 변환해야합니다 List<T>
.
You can remove in two ways
var output = from x in authorsList
where x.firstname != "Bob"
select x;
or
var authors = from x in authorsList
where x.firstname == "Bob"
select x;
var output = from x in authorsList
where !authors.Contains(x)
select x;
I had same issue, if you want simple output based on your where condition , then first solution is better.
Say that authorsToRemove
is an IEnumerable<T>
that contains the elements you want to remove from authorsList
.
Then here is another very simple way to accomplish the removal task asked by the OP:
authorsList.RemoveAll(authorsToRemove.Contains);
I think you could do something like this
authorsList = (from a in authorsList
where !authors.Contains(a)
select a).ToList();
Although I think the solutions already given solve the problem in a more readable way.
Below is the example to remove the element from the list.
List<int> items = new List<int>() { 2, 2, 3, 4, 2, 7, 3,3,3};
var result = items.Remove(2);//Remove the first ocurence of matched elements and returns boolean value
var result1 = items.RemoveAll(lst => lst == 3);// Remove all the matched elements and returns count of removed element
items.RemoveAt(3);//Removes the elements at the specified index
i think you just have to assign the items from Author list to a new list to take that effect.
//assume oldAuthor is the old list
Author newAuthorList = (select x from oldAuthor where x.firstname!="Bob" select x).ToList();
oldAuthor = newAuthorList;
newAuthorList = null;
To keep the code fluent (if code optimisation is not crucial) and you would need to do some further operations on the list:
authorsList = authorsList.Where(x => x.FirstName != "Bob").<do_some_further_Linq>;
or
authorsList = authorsList.Where(x => !setToRemove.Contains(x)).<do_some_further_Linq>;
LINQ has its origins in functional programming, which emphasises immutability of objects, so it doesn't provide a built-in way to update the original list in-place.
Note on immutability (taken from another SO answer):
Here is the definition of immutability from Wikipedia.
In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created.
Is very simple:
authorsList.RemoveAll((x) => x.firstname == "Bob");
참고URL : https://stackoverflow.com/questions/853526/using-linq-to-remove-elements-from-a-listt
'development' 카테고리의 다른 글
wget으로 위치를 지정하는 방법은 무엇입니까? (0) | 2020.10.02 |
---|---|
Git에서 충돌하는 파일을 나열하는 가장 간단한 방법은 무엇입니까? (0) | 2020.10.02 |
사용자가 아래로 스크롤했는지 확인 (0) | 2020.10.02 |
awk 또는 sed로 문자열을 재귀 적으로 찾기 / 바꾸는 방법은 무엇입니까? (0) | 2020.10.02 |
공백이 아닌 태그가 HTML5에서 유효한가요? (0) | 2020.10.02 |