受此启发 Majority vote from string[] using LINQ?
我正在尝试对像这样的字符串进行多数表决
var ips = new List<string>();
ips.Add("10.10.10.2");
ips.Add("10.10.10.2");
ips.Add("10.10.10.2");
ips.Add("10.10.10.2");
ips.Add("192.168.0.1");
ips.Add("192.168.0.1");
ips.Add("192.168.0.1");
ips.Add("192.168.0.1");
string majority = ips.GroupBy(s => s)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.First();
但是,如果字符串等于数字(请参见上文),我想返回FALSE 而不是第一项。
对我来说,这基本上是一个不确定的状态:)
有可能吗?
先谢谢您
答案 0 :(得分:2)
让我们找出 2 最高票,看看我们是否有 tie :
var data = ips
.GroupBy(s => s)
.Select(chunk => new {
value = chunk.Key,
count = chunk.Count()
})
.OrderByDescending(item => item.count)
.Take(2)
.ToArray();
string majority = (data.Length == 0) ||
(data.Length == 2) && (data[0].count == data[1].count)
? "No majority"
: data[0].value;
答案 1 :(得分:0)
您可以使用相当简单的扩展方法来做到这一点:
public static class Extensions
{
public static TResult FirstIfUniqueCount<TKey,TElement,TResult>(this IEnumerable<IGrouping<TKey,TElement>> items, Func<IGrouping<TKey,TElement>,TResult> selector)
{
if(!items.Any())
return default(TResult);
if(items.Count() < 2)
return selector(items.First());
var firstTwoItems = items.Take(2).ToArray();
if(firstTwoItems[0].Count() == firstTwoItems[1].Count())
return default(TResult);
return selector(firstTwoItems[0]);
}
}
用法:
string majority = ips.GroupBy(s => s)
.OrderByDescending(g => g.Count())
.FirstIfUniqueCount(g => g.Key);
如果没有多数(如果选择default(string)
之类的字符串,则返回null
),这将返回Key
。
实时示例:https://rextester.com/JHFG46105(取消注释不占多数的一行)
答案 2 :(得分:0)
检查有序可枚举的第一个分组元素的计数是否等于其余元素,如果是,则返回字符串False
,否则返回出现的第一个高位元素。
static void Main(string[] args)
{
var ips = new List<string>();
ips.Add("10.10.10.2");
ips.Add("10.10.10.2");
ips.Add("10.10.10.2");
ips.Add("10.10.10.2");
ips.Add("192.168.0.1");
ips.Add("192.168.0.1");
ips.Add("192.168.0.1");
ips.Add("192.168.0.1");
var groupedItems = ips
.GroupBy(s => s)
.Select(x => new
{
Key = x.Key,
Count = x.Count()
})
.OrderByDescending(x => x.Count);
string result = groupedItems.All(x => groupedItems.ElementAt(0).Count == x.Count) ? "False"
: groupedItems.FirstOrDefault().Key;
}