当序列包含默认值时,使用SingleOrDefault()
本文关键字:使用 SingleOrDefault 包含 默认值 | 更新日期: 2023-09-27 18:19:44
我偶然发现了一个有趣的场景,但我找不到解决方案。假设我必须找到序列中的多数(至少出现n / 2 + 1
次的数字,其中n
是序列的大小)。这是我的实现:
public static int FindMajorant(IList<int> numbers)
{
return numbers
.GroupBy(x => x)
.Where(g => g.Count() >= numbers.Count / 2 + 1)
.Select(g => g.Key)
.SingleOrDefault();
}
我使用的是SingleOrDefault()
,如果在序列中找到元素,它会返回元素或类型的默认值:在这种情况下,它将返回0
,因为它是int
的默认值。例如,我的方法返回以下序列的3
:
List<int> sampleNumbers = new List<int>() { 2, 2, 3, 3, 2, 3, 4, 3, 3 };
这是预期的行为。
然而,如果序列中的多数为零(0
),会发生什么?它会返回0,但那样的话,我怎么能确定它是SingleOrDefault()
中的零作为默认值,还是多数?也许,我可以使用Single()
,但这会抛出一个非常错误的异常。我也可能遇到这种例外,但这对我来说似乎是一种糟糕的做法。所以我的问题是,处理这种情况的首选方法是什么?
在null
表示不存在多数的情况下使用可为null的值,而不是使用"0"表示。非常方便的是,int?
的默认值是null
,因此代码所需的唯一更改就是在调用SingleOrDefault
之前获得一系列可为null的int。
public static int? FindMajorant(IList<int> numbers)
{
return numbers
.GroupBy(x => x)
.Where(g => g.Count() >= numbers.Count / 2 + 1)
.Select(g => (int?)g.Key)
.SingleOrDefault();
}
您可以将结果投影到一个类型化的对象中,比如MajorantResult
,然后返回null:
public static MajorantResult FindMajorant(IList<int> numbers)
{
return numbers
.GroupBy(x => x)
.Where(g => g.Count() >= numbers.Count/2 + 1)
.Select(g => new MajorantResult(g.Key))
.SingleOrDefault();
}
public class MajorantResult
{
public int Key { get; }
public MajorantResult(int key)
{
this.Key = key;
}
}