Linq GroupBy 将每个空值作为一个组
Linq GroupBy with each null value as a group
我有一个可以为 null 的 int 对象 属性 "GroupId".
有了这个对象的列表,我想在这个 "GroupId" 上做一个 GroupBy。但是如果我这样做,所有的空值将组成一个组。
示例:
对象 1:GroupId:NULL
对象 2:GroupId:NULL
对象 3:GroupId:1
对象 4:GroupId:1
对象 5:GroupId:2
对象 6:GroupId:2
MyList.GroupBy(f => f.GroupId, key => new {Object = key});
我会得到3组。
我怎样才能获得 4 个群组?每个 NULL 值一组...
这可能是最短的解决方案:
var grouped = MyList.GroupBy(f => f.GroupId != null ? (object)f.GroupId : new object(), key => new { Object = key });
请注意,组的 "key" 将是 object
类型。对于 null
个元素,我创建了一个新的 "empty" object
。对象的相等比较器将使它们都不同。对于非空数字,我只是将它们装在一个对象中。盒装整数维护相等运算符。所以:
new object().Equals(new object()) == false // always
和
((object)1).Equals((object)1) == true // always
和
((object)1).Equals((object)2) == false // always
更正确的解决方案是实施 IEqualityComparer<int?>
public class MyComparer : IEqualityComparer<int?> {
public bool Equals(int? x, int? y) {
if (x == null || y == null) {
return false;
}
return x.Value == y.Value;
}
public int GetHashCode(int? obj) {
return obj.GetHashCode(); // Works even if obj is null :-)
}
}
并使用它:
var grouped2 = MyList.GroupBy(f => f.GroupId, key => new { Object = key }, new MyComparer());
无需装箱即可使用的通用比较器。
public class NullableComparer<T> : IEqualityComparer<T?>
where T : struct
{
public bool Equals(T? x, T? y)
{
if (x == null || y == null)
{
return false;
}
return x.Equals(y);
}
public int GetHashCode(T? obj)
{
return obj.GetHashCode();
}
}
然后您可以像这样使用它:
// where GroupId as a nullable Guid
var grouped = MyList.GroupBy(f => f.GroupId, new NullableComparer<Guid>());
我有一个可以为 null 的 int 对象 属性 "GroupId".
有了这个对象的列表,我想在这个 "GroupId" 上做一个 GroupBy。但是如果我这样做,所有的空值将组成一个组。
示例:
对象 1:GroupId:NULL
对象 2:GroupId:NULL
对象 3:GroupId:1
对象 4:GroupId:1
对象 5:GroupId:2
对象 6:GroupId:2
MyList.GroupBy(f => f.GroupId, key => new {Object = key});
我会得到3组。
我怎样才能获得 4 个群组?每个 NULL 值一组...
这可能是最短的解决方案:
var grouped = MyList.GroupBy(f => f.GroupId != null ? (object)f.GroupId : new object(), key => new { Object = key });
请注意,组的 "key" 将是 object
类型。对于 null
个元素,我创建了一个新的 "empty" object
。对象的相等比较器将使它们都不同。对于非空数字,我只是将它们装在一个对象中。盒装整数维护相等运算符。所以:
new object().Equals(new object()) == false // always
和
((object)1).Equals((object)1) == true // always
和
((object)1).Equals((object)2) == false // always
更正确的解决方案是实施 IEqualityComparer<int?>
public class MyComparer : IEqualityComparer<int?> {
public bool Equals(int? x, int? y) {
if (x == null || y == null) {
return false;
}
return x.Value == y.Value;
}
public int GetHashCode(int? obj) {
return obj.GetHashCode(); // Works even if obj is null :-)
}
}
并使用它:
var grouped2 = MyList.GroupBy(f => f.GroupId, key => new { Object = key }, new MyComparer());
无需装箱即可使用的通用比较器。
public class NullableComparer<T> : IEqualityComparer<T?>
where T : struct
{
public bool Equals(T? x, T? y)
{
if (x == null || y == null)
{
return false;
}
return x.Equals(y);
}
public int GetHashCode(T? obj)
{
return obj.GetHashCode();
}
}
然后您可以像这样使用它:
// where GroupId as a nullable Guid
var grouped = MyList.GroupBy(f => f.GroupId, new NullableComparer<Guid>());