Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.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# 将多个lambda函数与高效执行结合在一起_C#_Lambda - Fatal编程技术网

C# 将多个lambda函数与高效执行结合在一起

C# 将多个lambda函数与高效执行结合在一起,c#,lambda,C#,Lambda,我正在尝试使用lambda函数的组合创建一个动态过滤器。但是lambda函数的数量可能会根据用户应用的不同过滤器的数量而有所不同 我想要这样的东西 //images is a List<ImageInfo> var result1 = images .Where(image => image.Bytes < 1000) .Where(image => image.Height < 100) .Where(image => image.Width <

我正在尝试使用lambda函数的组合创建一个动态过滤器。但是lambda函数的数量可能会根据用户应用的不同过滤器的数量而有所不同

我想要这样的东西

//images is a List<ImageInfo>
var result1 = images
.Where(image => image.Bytes < 1000)
.Where(image => image.Height < 100)
.Where(image => image.Width < 100);
//图像是一个列表
var result1=图像
.Where(image=>image.Bytes<1000)
.Where(图像=>image.Height<100)
.其中(图像=>图像宽度<100);
其中,高度过滤器仅应用于通过字节过滤器的图像。宽度过滤器仅应用于通过高度过滤器的图像

但是,用户打开和关闭过滤器的动态方式不允许我创建一个lambda函数

相反,我将创建一个lambda函数列表,然后需要将它们应用于图像列表。所以我最终会得到这样的结果;多个单独的lambda函数

var filter1 = images.Where(image => image.Bytes < 1000);
var filter2 = images.Where(image => image.Height < 100);
var filter3 = images.Where(image => image.Width < 100);
var filter1=images.Where(image=>image.Bytes<1000);
var filter2=images.Where(image=>image.Height<100);
var filter3=images.Where(image=>image.Width<100);
如何将多个lambda函数连接在一起以获得最终的过滤图像列表

是我干的

var result = filter1.Intersect<ImageInfo>(filter2).Intersect<ImageInfo>(filter3);
var result=filter1.Intersect(filter2.Intersect(filter3);
但每个过滤器都会旋转主图像列表以获得其图像子集,然后进行交集计算,这占用了太多的CPU


因此,我要寻找的是一种方法,可以获取任意的lambda函数列表(表达式…无论什么),并以我展示的第一个示例的方式将它们连接起来。

为什么不像第一个示例那样,一个接一个地应用函数呢

您的过滤器具有以下签名:

Func<IEnumerable<ImageInfo>, IEnumerable<ImageInfo>> 
Func
那么只需将每个过滤器应用于最后一个过滤器的结果

像这样

IEnumerable<ImageInfo> filtered = images;

if(filterByBytes)
    filtered = filtered.Where(image => image.Bytes < 1000);

if(filterByHeight)
    filtered = filtered.Where(image => image.Height < 100);

if(filterByWidth)
    filtered = filtered.Where(image => image.Width < 100);
IEnumerable filtered=图像;
if(滤波器字节)
filtered=filtered.Where(image=>image.Bytes<1000);
if(过滤器重量)
过滤=过滤。其中(图像=>图像高度<100);
if(过滤器宽度)
过滤=过滤。其中(image=>image.Width<100);
编辑回复:评论,在我的头顶上,像

List<Func<IEnumerable<ImageInfo>, IEnumerable<ImageInfo>>> lambdas = new List<Func<IEnumerable<ImageInfo>, IEnumerable<ImageInfo>>>();

lambdas.add(x => x.Where(image => image.Bytes < 1000));
lambdas.add(x => x.Where(image => image.Height < 100));
lambdas.add(x => x.Where(image => image.Width < 100));

foreach(var lambda in lambdas)
    images = lamdba.Invoke(images);
List lambdas=new List();
add(x=>x.Where(image=>image.Bytes<1000));
add(x=>x.Where(image=>image.Height<100));
add(x=>x.Where(image=>image.Width<100));
foreach(lambdas中的var lambda)
images=lamdba.Invoke(images);
好的,那么:

static Func<T, bool> CombineWithAnd<T>(IEnumerable<Func<T, bool>> filters)
{
    return x =>
    {
        foreach (var filter in filters)
        {
            if (!filter(x))
            {
                return false;
            }
        }
        return true;
    };
}

作为第一行的方法,要有效地进行复制。请注意,代理是不可变的,因此您无需担心它们的变化。

哦,太好了!你离得很近,但离得够近了,让我知道答案。要应用所有过滤器,
返回true
需要移动到foreach循环之外(如下所示)。但是是的,这正是我想要的

一个问题或评论。这个函数真正让我吃惊的是x变量。我必须运行并调试代码,以确定x的类型是
。我以前从未见过一个变量没有类型或var声明,这让我很困惑。你能解释一下允许变量x不做任何声明的C#规则吗

顺便说一下,这是一个非常优雅的解决方案

static Func<T, bool> CombineWithAnd<T>(IEnumerable<Func<T, bool>> filters)
{
    return x =>
    {
        foreach (var filter in filters)
        {
            if (!filter(x))
            {
                return false;
            }
        }
        return true;
    };
}
静态函数组合法(IEnumerable过滤器)
{
返回x=>
{
foreach(过滤器中的var过滤器)
{
如果(!过滤器(x))
{
返回false;
}
}
返回true;
};
}

不管它值多少钱,您都不需要使用循环。(在Python中,因为我没有使用C:)


True,我可以这样做,但是因为过滤器列表是相当动态的(可以随时从任何源添加新的过滤器),我希望将lambda函数存储在lambda函数列表中,然后旋转列表,一次应用一个。如何将lambda函数存储为变量?记住lambda只是委托(函数调用)。从我的答案“Func”中,这是一个代理的类型,它接受imageinfo的IEnum并返回sameDoh,谢谢,修复了我的答案。lambda表达式参数的规则基本上是,如果编译器可以根据lambda表达式必须转换的内容计算出它们的类型,则不必显式指定类型。
filters = filters.ToList();
static Func<T, bool> CombineWithAnd<T>(IEnumerable<Func<T, bool>> filters)
{
    return x =>
    {
        foreach (var filter in filters)
        {
            if (!filter(x))
            {
                return false;
            }
        }
        return true;
    };
}
def conjoin(filter1, filter2):
    return lambda x: filter1(x) and filter2(x)

def conjoin_list(filters):
    return reduce(conjoin, filters)