C #에서 컬렉션을 필터링하는 매우 빠른 방법을 찾고 있습니다. 나는 현재 일반적인 List <object> 컬렉션을 사용하고 있지만 더 나은 성능을 발휘한다면 다른 구조를 사용할 수 있습니다.
현재 새 List <object>를 만들고 원래 목록을 통해 반복하고 있습니다. 필터링 기준이 일치하면 새 목록에 사본을 넣습니다.
더 좋은 방법이 있습니까? 임시 목록이 필요하지 않도록 필터링 할 수있는 방법이 있습니까?
C #에서 컬렉션을 필터링하는 매우 빠른 방법을 찾고 있습니다. 나는 현재 일반적인 List <object> 컬렉션을 사용하고 있지만 더 나은 성능을 발휘한다면 다른 구조를 사용할 수 있습니다.
현재 새 List <object>를 만들고 원래 목록을 통해 반복하고 있습니다. 필터링 기준이 일치하면 새 목록에 사본을 넣습니다.
더 좋은 방법이 있습니까? 임시 목록이 필요하지 않도록 필터링 할 수있는 방법이 있습니까?
답변:
C # 3.0을 사용하는 경우 linq를 더 잘 사용하고 더 우아하게 사용할 수 있습니다.
List<int> myList = GetListOfIntsFromSomewhere();
// This will filter out the list of ints that are > than 7, Where returns an
// IEnumerable<T> so a call to ToList is required to convert back to a List<T>.
List<int> filteredList = myList.Where( x => x > 7).ToList();
를 찾을 수 없으면 파일 상단에서 .Where
가져와야 using System.Linq;
합니다.
.Where(predefinedQuery)
대신 사용하려면 .Where(x => x > 7)
public bool predefinedQuery(int x) { return x > 7; }
. 그렇다면 .Where(predefinedQuery)
잘 작동합니다.
다음은 Lambdas 및 LINQ 기반 목록 필터링을 보여주기 위해 함께 세 가지 다른 방법을 사용하는 일부 목록 필터링의 코드 블록 / 예입니다.
#region List Filtering
static void Main(string[] args)
{
ListFiltering();
Console.ReadLine();
}
private static void ListFiltering()
{
var PersonList = new List<Person>();
PersonList.Add(new Person() { Age = 23, Name = "Jon", Gender = "M" }); //Non-Constructor Object Property Initialization
PersonList.Add(new Person() { Age = 24, Name = "Jack", Gender = "M" });
PersonList.Add(new Person() { Age = 29, Name = "Billy", Gender = "M" });
PersonList.Add(new Person() { Age = 33, Name = "Bob", Gender = "M" });
PersonList.Add(new Person() { Age = 45, Name = "Frank", Gender = "M" });
PersonList.Add(new Person() { Age = 24, Name = "Anna", Gender = "F" });
PersonList.Add(new Person() { Age = 29, Name = "Sue", Gender = "F" });
PersonList.Add(new Person() { Age = 35, Name = "Sally", Gender = "F" });
PersonList.Add(new Person() { Age = 36, Name = "Jane", Gender = "F" });
PersonList.Add(new Person() { Age = 42, Name = "Jill", Gender = "F" });
//Logic: Show me all males that are less than 30 years old.
Console.WriteLine("");
//Iterative Method
Console.WriteLine("List Filter Normal Way:");
foreach (var p in PersonList)
if (p.Gender == "M" && p.Age < 30)
Console.WriteLine(p.Name + " is " + p.Age);
Console.WriteLine("");
//Lambda Filter Method
Console.WriteLine("List Filter Lambda Way");
foreach (var p in PersonList.Where(p => (p.Gender == "M" && p.Age < 30))) //.Where is an extension method
Console.WriteLine(p.Name + " is " + p.Age);
Console.WriteLine("");
//LINQ Query Method
Console.WriteLine("List Filter LINQ Way:");
foreach (var v in from p in PersonList
where p.Gender == "M" && p.Age < 30
select new { p.Name, p.Age })
Console.WriteLine(v.Name + " is " + v.Age);
}
private class Person
{
public Person() { }
public int Age { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
}
#endregion
List<T>
FindAll
필터링을 수행하고 목록의 하위 집합을 반환 하는 메서드가 있습니다.
MSDN에는 훌륭한 코드 예제가 있습니다. http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx
편집 : 나는 LINQ와 Where()
방법을 잘 이해하기 전에 이것을 썼습니다 . 오늘이 글을 쓰려면 위의 호르헤 언급 방법을 사용했을 것입니다. FindAll
그래도 .NET 2.0 환경에 갇혀 있으면 이 방법이 여전히 작동합니다.
IEnumerable을 사용하여 임시 목록이 필요하지 않습니다.
public IEnumerable<T> GetFilteredItems(IEnumerable<T> collection)
{
foreach (T item in collection)
if (Matches<T>(item))
{
yield return item;
}
}
여기서 Matches는 필터 방법의 이름입니다. 그리고 당신은 이것을 다음과 같이 사용할 수 있습니다 :
IEnumerable<MyType> filteredItems = GetFilteredItems(myList);
foreach (MyType item in filteredItems)
{
// do sth with your filtered items
}
필요한 경우 GetFilteredItems 함수를 호출하고 경우에 따라 필터링 된 컬렉션에서 모든 항목을 사용하지 않으면 성능이 약간 향상 될 수 있습니다.