Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C语言过滤集合#_C#_Collections_Filtering - Fatal编程技术网

C# 用C语言过滤集合#

C# 用C语言过滤集合#,c#,collections,filtering,C#,Collections,Filtering,我正在寻找一种非常快速的方法来过滤C#中的集合。我目前使用的是泛型列表集合,但如果它们性能更好,我愿意使用其他结构 目前,我正在创建一个新的列表,并在原始列表中循环。如果筛选条件匹配,我会将一份副本放入新列表中 有更好的方法吗?是否有一种方法可以进行适当的筛选,从而不需要临时列表?如果您使用的是C#3.0,那么您可以使用linq,它更好、更优雅: List myList=getlistofinitsfromwhere(); //这将过滤列表中不大于7的整数;返回一个 //IEnumerable,

我正在寻找一种非常快速的方法来过滤C#中的集合。我目前使用的是泛型列表集合,但如果它们性能更好,我愿意使用其他结构

目前,我正在创建一个新的列表,并在原始列表中循环。如果筛选条件匹配,我会将一份副本放入新列表中

有更好的方法吗?是否有一种方法可以进行适当的筛选,从而不需要临时列表?

如果您使用的是C#3.0,那么您可以使用linq,它更好、更优雅:

List myList=getlistofinitsfromwhere();
//这将过滤列表中不大于7的整数;返回一个
//IEnumerable,因此调用ToList将其转换回列表。
List filteredList=myList.Where(x=>x>7.ToList();
如果找不到
.Where
,则意味着您需要使用System.Linq导入
位于文件顶部。

List
有一个
FindAll
方法,该方法将为您执行筛选并返回列表的子集

MSDN在这里有一个很好的代码示例:


编辑:在我对LINQ和
Where()
方法有了很好的理解之前,我写了这篇文章。如果我今天写这篇文章,我可能会使用豪尔赫上面提到的方法。如果您被困在.NET 2.0环境中,
FindAll
方法仍然有效。

要就地执行,您可以使用“List”类的RemoveAll方法以及自定义的“Predicate”类……但所做的只是清理代码。。。在引擎盖下,它正在做与您相同的事情…但是,是的,它在适当的位置执行,因此您可以对临时列表执行相同的操作。

您可以使用IEnumerable来消除临时列表的需要

public IEnumerable<T> GetFilteredItems(IEnumerable<T> collection)
{
    foreach (T item in collection)
    if (Matches<T>(item))
    {
        yield return item;
    }
}
public IEnumerable GetFilteredItems(IEnumerable集合)
{
foreach(集合中的T项)
如果(匹配(项目))
{
收益回报项目;
}
}
其中Matches是筛选方法的名称。您可以这样使用:

IEnumerable<MyType> filteredItems = GetFilteredItems(myList);
foreach (MyType item in filteredItems)
{
    // do sth with your filtered items
}
IEnumerable filteredItems=GetFilteredItems(myList);
foreach(filteredItems中的MyType项)
{
//用过滤过的物品做某事
}
这将在需要时调用GetFilteredItems函数,在某些情况下,如果您没有使用筛选集合中的所有项,则可能会提供一些良好的性能增益。

您可以使用列表的方法,提供一个要筛选的委托。不过,我同意@的说法,除非是一个庞大的清单,否则你不值得为自己操心太多

如果您使用的是C#3.0,那么可以使用linq

或者,如果愿意,可以使用C#3编译器提供的特殊查询语法:

var filteredList = from x in myList
                   where x > 7
                   select x;

下面是使用三种不同方法进行列表过滤的代码块/示例,我将它们放在一起展示基于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
#区域列表筛选
静态void Main(字符串[]参数)
{
ListFiltering();
Console.ReadLine();
}
私有静态void ListFiltering()
{
var PersonList=新列表();
Add(new Person(){Age=23,Name=“Jon”,Gender=“M”});//非构造函数对象属性初始化
添加(newperson(){Age=24,Name=“Jack”,Gender=“M”});
添加(newperson(){Age=29,Name=“Billy”,Gender=“M”});
添加(newperson(){Age=33,Name=“Bob”,Gender=“M”});
添加(newperson(){Age=45,Name=“Frank”,Gender=“M”});
添加(newperson(){Age=24,Name=“Anna”,Gender=“F”});
添加(newperson(){Age=29,Name=“Sue”,Gender=“F”});
添加(newperson(){Age=35,Name=“Sally”,Gender=“F”});
添加(newperson(){Age=36,Name=“Jane”,Gender=“F”});
添加(newperson(){Age=42,Name=“Jill”,Gender=“F”});
//逻辑:让我看看所有30岁以下的男性。
控制台。写线(“”);
//迭代法
WriteLine(“列表过滤器正常方式:”);
foreach(个人列表中的var p)
如果(p.性别==“M”和p.年龄<30岁)
Console.WriteLine(p.Name+“是”+p.Age);
控制台。写线(“”);
//Lambda滤波法
Console.WriteLine(“列表过滤器Lambda方式”);
foreach(PersonList.Where中的var p(p=>(p.Gender==“M”和p.Age<30))/,其中是一个扩展方法
Console.WriteLine(p.Name+“是”+p.Age);
控制台。写线(“”);
//LINQ查询方法
WriteLine(“列表过滤器LINQ方式:”);
foreach(变量v从个人列表中的p开始
其中p.性别==“M”&p.年龄<30
选择新的{p.名称,p.年龄})
Console.WriteLine(v.Name+“是”+v.Age);
}
私人阶级人士
{
公众人物(){}
公共整数{get;set;}
公共字符串名称{get;set;}
公共字符串{get;set;}
}
#端区

使用LINQ比使用提供给列表
FindAll
方法的谓词要慢得多。还要注意使用LINQ,因为在访问结果之前,
列表的枚举实际上不会执行。这可能意味着,当您认为自己已经创建了一个过滤列表时,内容可能与您实际阅读时预期的内容不同。

如果您的列表很大,并且您正在重复过滤,则您可以在“过滤器”属性上对原始列表进行排序,通过二进制搜索找到起始点和结束点

初始时间O(n*log(n))然后O(log(n))


标准筛选每次都需要O(n)。

对于按字符串筛选,这是如何工作的。就像查找以“ch”@JonathanO开头的字符串列表中的所有项一样,您可以使用Func中的方法。listofstring.Where(s=>s.StartsWith(“ch”).ToList();有没有一种方法可以客观化linq查询?例如,要使用
.Where(predefinedQuery)
而不是使用
.Where(x=>x>7)
?@AlmightyR:只需将其定义为一个接受一个参数的方法即可。例如:
public bool预定义查询(intx){return x>7;}
。那你呢