多数投票通过相等时失败的字符串

时间:2019-05-21 15:51:03

标签: c# linq

受此启发 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 而不是第一项。

对我来说,这基本上是一个不确定的状态:)

有可能吗?

先谢谢您

3 个答案:

答案 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;
}