Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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#_Linq_Filter_Collections - Fatal编程技术网

C# 是否有基于不同条件从集合中获取元素/变量的最佳实践

C# 是否有基于不同条件从集合中获取元素/变量的最佳实践,c#,linq,filter,collections,C#,Linq,Filter,Collections,或者,一般来说,如何在单通道中根据不同和复杂的条件从集合中筛选某些元素 假设我们有元素集合 var cats = new List<Cat>{ new Cat("Fluffy"), new Cat("Meowista"), new Cat("Scratchy")}; 三元op的所有选项都不易扩展,且相对容易出错,但都非常简短且不明确,它们还依赖于不返回/使用三元op的实际结果(使用discard“uu”或“is null”作为bool)。我认为使用Funcs字典的方法是实现自定义条

或者,一般来说,如何在单通道中根据不同和复杂的条件从集合中筛选某些元素

假设我们有元素集合

var cats = new List<Cat>{ new Cat("Fluffy"), new Cat("Meowista"), new Cat("Scratchy")};
三元op的所有选项都不易扩展,且相对容易出错,但都非常简短且不明确,它们还依赖于不返回/使用三元op的实际结果(使用discard“uu”或“is null”作为bool)。我认为使用Funcs字典的方法是实现自定义条件的一个很好的候选方法,只需将它们与变量一起烘焙即可


谢谢,期待您的解决方案!:)

我不确定Linq是否可以开箱即用,但如果您可以选择编写一次自定义扩展,那么从具有任意数量条件的集合中检索某些值以后可能会非常简洁

例如,您可以编写如下内容

var (redCat, blueCat) = cats.FindFirsts(
    x => x.Name == redCatName,
    x => x.Name == blueCatName);
如果引入
FindFirsts()
扩展,如下所示:

public static class FindExtensions
{
    public static T[] FindFirsts<T>(this IEnumerable<T> collection, 
        params Func<T, bool>[] conditions)
    {
        if (conditions.Length == 0)
            return new T[] { };

        var unmatchedConditions = conditions.Length;
        var lookupWork = conditions
            .Select(c => (
                value: default(T),
                found: false,
                cond: c
            ))
            .ToArray();
        foreach (var item in collection) 
        {
            for (var i = 0; i < lookupWork.Length; i++)
            {
                if (!lookupWork[i].found && lookupWork[i].cond(item))
                { 
                    lookupWork[i].found = true;
                    lookupWork[i].value = item;
                    unmatchedConditions--;
                }
            }
            if (unmatchedConditions <= 0)
                break;
        }
        return lookupWork.Select(x => x.value).ToArray();
    }
}
公共静态类findex
{
公共静态T[]FindFirsts(此IEnumerable集合,
参数Func[]条件)
{
if(conditions.Length==0)
返回新的T[]{};
var unmatchedConditions=条件.Length;
var lookupWork=条件
.选择(c=>(
值:默认值(T),
发现:错,
条件:c
))
.ToArray();
foreach(集合中的var项)
{
for(var i=0;i
完整的演示可以在这里进行:


注意:为了解构结果数组(即使用
var(redCat,blueCat)=…
),您必须定义解构扩展。为此,我从中借用了一些代码。

我不确定使用Linq开箱即用是否可行,但如果您可以选择编写一次自定义扩展,则从具有任意数量条件的集合中检索某些值以后可能会非常简洁

例如,您可以编写如下内容

var (redCat, blueCat) = cats.FindFirsts(
    x => x.Name == redCatName,
    x => x.Name == blueCatName);
如果引入
FindFirsts()
扩展,如下所示:

public static class FindExtensions
{
    public static T[] FindFirsts<T>(this IEnumerable<T> collection, 
        params Func<T, bool>[] conditions)
    {
        if (conditions.Length == 0)
            return new T[] { };

        var unmatchedConditions = conditions.Length;
        var lookupWork = conditions
            .Select(c => (
                value: default(T),
                found: false,
                cond: c
            ))
            .ToArray();
        foreach (var item in collection) 
        {
            for (var i = 0; i < lookupWork.Length; i++)
            {
                if (!lookupWork[i].found && lookupWork[i].cond(item))
                { 
                    lookupWork[i].found = true;
                    lookupWork[i].value = item;
                    unmatchedConditions--;
                }
            }
            if (unmatchedConditions <= 0)
                break;
        }
        return lookupWork.Select(x => x.value).ToArray();
    }
}
公共静态类findex
{
公共静态T[]FindFirsts(此IEnumerable集合,
参数Func[]条件)
{
if(conditions.Length==0)
返回新的T[]{};
var unmatchedConditions=条件.Length;
var lookupWork=条件
.选择(c=>(
值:默认值(T),
发现:错,
条件:c
))
.ToArray();
foreach(集合中的var项)
{
for(var i=0;i
完整的演示可以在这里进行:


注意:为了解构结果数组(即使用
var(redCat,blueCat)=…
),您必须定义解构扩展。为此,我从中借用了一些代码。

您的意思是像
cats。其中(x=>x.Name==redCatName | | x.Name==blueCatName)?你认为什么是“好”的方法?你问一个单程,所以看起来你关心的是性能。另一方面,你需要一个可读的OneliNER。在我的经验中,这2个要求经常冲突。对于Onelier-Posits,重要的是要知道,例如,你可以使用的多行通用扩展方法。那么作为一条直线使用是可以接受的吗?@Magnetron,实际上不是,我更喜欢在不同的“命名变量”中使用它们正如您在MarchBoxing方法中所看到的,一般来说,它就像将集合反汇编回单独的集合elements@Knoop,是的,这些是相互冲突的,但正如您在我的不同方法中看到的,它们非常适合所要求的内容,但也许有人可以做得更好?我们也很欣赏通用扩展方法,但这样我们仍然可以必须在调用方的site@VladFomin我可以问一下为什么吗?就我所见,你不需要知道哪个是“红猫”,哪个是蓝猫,一旦你有了它们,你就可以比较并返回winner cat对象。一旦你有了它们,把它们分配给“命名变量”是很便宜的你的意思是像
cats.Where(x=>x.Name==redCatName | | x.Name==blueCatName)?你认为什么是“好”的方法?你问一个单程,所以看起来你关心的是性能。另一方面,你需要一个可读的OneliNER。在我的经验中,这2个要求经常冲突。对于Onelier-Posits,重要的是要知道,例如,你可以使用的多行通用扩展方法。那么作为一条直线使用是可以接受的吗?@Magnetron,实际上不是,我更喜欢在不同的“命名变量”中使用它们正如您在MarchBoxing方法中所看到的,一般来说,它就像将集合反汇编回单独的集合elements@Knoop,是的,这些是相互冲突的,但正如您在我的不同方法中看到的,它们非常适合所要求的内容,但也许有人可以做得更好?我们也很欣赏通用扩展方法,但这样我们仍然可以必须在调用方的site@VladFomin我可以问为什么吗?就我所见,你不需要知道哪个是“红猫”,哪个是“红猫”