我偶然发现了一个有趣的场景,我无法找到解决方案。假设我必须在序列中找到majorant(数量至少发生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
as它是int
的默认值。例如,我的方法返回3
以获得以下序列:
List<int> sampleNumbers = new List<int>() { 2, 2, 3, 3, 2, 3, 4, 3, 3 };
这是预期的行为。
然而,如果序列中的主要部分为零(0
)会发生什么?它会返回0,但是那样,我怎样才能确定它是SingleOrDefault()
的零作为默认值,还是majorant?也许,我可以使用Single()
,但这会引发一个非常不正常的例外。我也可以抓住这个例外,但这对我来说似乎是一个不好的做法。所以我的问题是,处理这种情况的首选方法是什么?
答案 0 :(得分:8)
使用可以为空的值,其中null
表示没有主要内容,而不是使用“0”表示。而且很方便,int?
的默认值为null
,因此您的代码所需的唯一更改是在调用SingleOrDefault
之前获取一系列可为空的整数。
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();
}
答案 1 :(得分:0)
您可以将结果投影到类型化的对象中说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;
}
}