C# Linq按多个值和空白值分组

C# Linq按多个值和空白值分组,c#,linq,C#,Linq,我需要能够根据多个值进行分组,但也需要在值为空时进行匹配 public class ExampleClass { public string FieldX { set; get; } public string FieldY { set; get; } public string FieldZ { set; get; } public string FieldA { set; get; } publi

我需要能够根据多个值进行分组,但也需要在值为空时进行匹配

    public class ExampleClass
    {
        public string FieldX { set; get; }
        public string FieldY { set; get; }
        public string FieldZ { set; get; }
        public string FieldA { set; get; }
        public string FieldB { set; get; }
        public string FieldC { set; get; }
    }

    var obj1 = new ExampleClass{
            FieldA = "AAA",
            FieldB = "BBB",
            FieldC = "CCC",
            FieldX = "Matched",
            FieldY = "Matched",
            FieldZ = "Matched"
        };

    var obj2 = new ExampleClass{
        FieldA = "ada a",
        FieldB = "BBBada ",
        FieldC = "CCadasd aC",
        FieldX = "Matched",
        FieldY = "Matched",
        FieldZ = "Matched"
    };
    var obj3 = new ExampleClass{
        FieldA = "AfsfAA",
        FieldB = "BBsfsfB",
        FieldC = "CsfsghsCC",
        FieldX = "",
        FieldY = "Matched",
        FieldZ = "Matched"
    };

    var obj4 = new ExampleClass{
        FieldA = "AAA",
        FieldB = "BBB",
        FieldC = "CCC",
        FieldX = "Not Matched",
        FieldY = "Not Matched",
        FieldZ = "Matched"
    };
    var list = new List<ExampleClass>(new ExampleClass[] { obj1, obj2, obj3, obj4 } );
    var grp = list.GroupBy(x => new { x.FieldX, x.FieldY, x.FieldZ });
但我需要平等

//grp = [{[obj1, obj2, obj3]}, {[obj4]}]
希望有一种有效的方法可以在没有多个嵌套循环的情况下实现这一点


非常感谢。

我想这可能会对你有所帮助 (我正在添加一个,以便您可以使用它)

使用系统;
使用System.Linq;
使用System.Collections.Generic;
公共课程
{
公共类示例类
{
公共字符串字段x{set;get;}
公共字符串字段{set;get;}
公共字符串字段z{set;get;}
公共字符串字段a{set;get;}
公共字符串字段B{set;get;}
公共字符串字段C{set;get;}
}
公共类IncludeBlankComparer:IEqualityComparer
{
公共静态bool IsBlank(string s)=>string.IsNullOrEmpty(s);
私有静态bool IsMatchOrBlankMatch(字符串左、字符串右)=>left==right | | IsBlank(左)| | IsBlank(右);
公共布尔等于((字符串a、字符串b、字符串c)第一,(字符串a、字符串b、字符串c)第二)
{ 
if(first==second)返回true;
返回isMatcherLankMatch(first.a,second.a)
&&IsMatcherBlankMatch(first.b,second.b)
&&IsMatcherBlankMatch(first.c,second.c);
}
public int GetHashCode((字符串a、字符串b、字符串c)s)=>0;
}
公共静态void Main()
{
var obj1=新示例类{
FieldA=“AAA”,
FieldB=“BBB”,
FieldC=“CCC”,
FieldX=“匹配”,
FieldY=“匹配”,
FieldZ=“匹配”
};
var obj2=新的ExampleClass{
FieldA=“ada a”,
FieldB=“BBBada”,
FieldC=“CCadasd aC”,
FieldX=“匹配”,
FieldY=“匹配”,
FieldZ=“匹配”
};
var obj3=新示例类{
FieldA=“AfsfAA”,
FieldB=“BBsfsfB”,
FieldC=“CsfsghsCC”,
FieldX=“”,
FieldY=“匹配”,
FieldZ=“匹配”
};
var obj4=新示例类{
FieldA=“AAA”,
FieldB=“BBB”,
FieldC=“CCC”,
FieldX=“不匹配”,
FieldY=“不匹配”,
FieldZ=“匹配”
};
var list=新列表(新示例类[]{obj1、obj2、obj3、obj4});
var grp=list.GroupBy(x=>(x.FieldX,x.FieldY,x.FieldZ),新的IncludeBlankComparer();
grp.Dump();
}
}
解释:您可以将自定义比较器传递给GroupBy方法。 当然,比较器必须处理与键相同类型的比较。 注意,我已经将键选择器从匿名类(在其中我不能引用内部成员)更改为元组(在其中我可以)

注意:此解决方案仅适用于具有3个字符串部分的元组键


注2:由于此解决方案的黑客性质,我不得不使用
GetHashCode()=>0
。这将用作相等和哈希代码相等的比较,不会破坏GroupBy的实现,但它本身不是一个“干净”的解决方案。

我认为这可能会对您有所帮助 (我正在添加一个,以便您可以使用它)

使用系统;
使用System.Linq;
使用System.Collections.Generic;
公共课程
{
公共类示例类
{
公共字符串字段x{set;get;}
公共字符串字段{set;get;}
公共字符串字段z{set;get;}
公共字符串字段a{set;get;}
公共字符串字段B{set;get;}
公共字符串字段C{set;get;}
}
公共类IncludeBlankComparer:IEqualityComparer
{
公共静态bool IsBlank(string s)=>string.IsNullOrEmpty(s);
私有静态bool IsMatchOrBlankMatch(字符串左、字符串右)=>left==right | | IsBlank(左)| | IsBlank(右);
公共布尔等于((字符串a、字符串b、字符串c)第一,(字符串a、字符串b、字符串c)第二)
{ 
if(first==second)返回true;
返回isMatcherLankMatch(first.a,second.a)
&&IsMatcherBlankMatch(first.b,second.b)
&&IsMatcherBlankMatch(first.c,second.c);
}
public int GetHashCode((字符串a、字符串b、字符串c)s)=>0;
}
公共静态void Main()
{
var obj1=新示例类{
FieldA=“AAA”,
FieldB=“BBB”,
FieldC=“CCC”,
FieldX=“匹配”,
FieldY=“匹配”,
FieldZ=“匹配”
};
var obj2=新的ExampleClass{
FieldA=“ada a”,
FieldB=“BBBada”,
FieldC=“CCadasd aC”,
FieldX=“匹配”,
FieldY=“匹配”,
FieldZ=“匹配”
};
var obj3=新示例类{
FieldA=“AfsfAA”,
FieldB=“BBsfsfB”,
FieldC=“CsfsghsCC”,
FieldX=“”,
FieldY=“匹配”,
FieldZ=“匹配”
};
var obj4=新示例类{
FieldA=“AAA”,
FieldB=“BBB”,
FieldC=“CCC”,
FieldX=“不匹配”,
FieldY=“不匹配”,
FieldZ=“匹配”
};
var list=新列表(新示例类[]{obj1、obj2、obj3、obj4});
var grp=list.GroupBy(x=>(x.FieldX,x.FieldY,x.FieldZ),新的IncludeBlankComparer();
grp.Dump();
}
}
解释:您可以将自定义比较器传递给GroupBy方法。 当然,比较器必须处理与键相同类型的比较。 请注意,我已将密钥选择器从匿名类(其中我无法引用内部
//grp = [{[obj1, obj2, obj3]}, {[obj4]}]