使用LINQ获取包括重复项的前n个值

huangapple go评论64阅读模式
英文:

Get top n values including duplicates with LINQ

问题

以下是翻译好的部分:

请考虑这个列表:

城市            值
---------------------
城市1             10
城市2             20
城市3             30
城市4             40
城市5             50
城市6             60

如果我想要获取前3个城市中的最高值,我可以编写以下的LINQ查询:

MyList.OrderByDescending(o=>o.Value).Take(3);

现在考虑这个列表:

城市            值
---------------------
城市1             10
城市2             20
城市3             30
城市4             40
城市5             50
城市6             60
城市7             60

我想要一个查询,返回所有具有前3个最高值的城市。对于上述列表,我想要以下结果:

城市            值
---------------------
城市7             60
城市6             60
城市5             50
城市4             40

谢谢。

英文:

Please consider this list:

City            Value
---------------------
City1             10
City2             20
City3             30
City4             40
City5             50
City6             60

If I want to get top 3 Values in Cities I can write this LINQ:

MyList.OrderByDescending(o=>o.Value).Take(3);

Now consider this list:

City            Value
---------------------
City1             10
City2             20
City3             30
City4             40
City5             50
City6             60
City7             60

I want a query that return all cities with top 3 highest values. For above list I want this result:

City            Value
---------------------
City7             60
City6             60
City5             50
City4             40

Thanks

答案1

得分: 14

This list will contain all cities with the top 3 highest values, sorted in descending order by value.

英文:
var result = MyList.GroupBy(o => o.Value)
                   .OrderByDescending(g => g.Key)
                   .Take(3)
                   .SelectMany(g => g)
                   .ToList();

This list will contain all cities with the top 3 highest values, sorted in descending order by value.

答案2

得分: 0

A bit clunky, this solution finds the third highest DISTINCT value, then returns all values equal or greater to it.

using System.Diagnostics.CodeAnalysis;

var MyList = new List<(string, string)>();
MyList.Add(("City1", "10"));
MyList.Add(("City2", "20"));
MyList.Add(("City3", "30"));
MyList.Add(("City4", "40"));
MyList.Add(("City5", "50"));
MyList.Add(("City6", "60"));
MyList.Add(("City7", "60"));
var topThreeDistinct = MyList.Distinct(new StringStringComparer()).OrderByDescending(o => o.Item2).Take(3).ToList();

var thirdValue = topThreeDistinct[2].Item2;
Console.WriteLine($"Third value = {thirdValue}");

var topThreeAll = MyList.Where(o => o.Item2.CompareTo(thirdValue) >= 0 ).ToList();
foreach (var item in topThreeAll)
    Console.WriteLine(item);
Console.WriteLine("FINISHED");

class StringStringComparer : IEqualityComparer<(string, string)>
{
    public bool Equals((string, string) x, (string, string) y)
    {
        if (x.Item2 == y.Item2)
        {
            return true;
        }
        else
        {
            return false;
        };
    }

    public int GetHashCode([DisallowNull] (string, string) obj)
    {
        return Convert.ToInt32(obj.Item2);
    }
}

(C# .NET 6.0 Console App)

英文:

A bit clunky, this solution finds the third highest DISTINCT value, then returns all values equal or greater to it.

using System.Diagnostics.CodeAnalysis;

var MyList = new List&lt;(string, string)&gt;();
MyList.Add((&quot;City1&quot;, &quot;10&quot;));
MyList.Add((&quot;City2&quot;, &quot;20&quot;));
MyList.Add((&quot;City3&quot;, &quot;30&quot;));
MyList.Add((&quot;City4&quot;, &quot;40&quot;));
MyList.Add((&quot;City5&quot;, &quot;50&quot;));
MyList.Add((&quot;City6&quot;, &quot;60&quot;));
MyList.Add((&quot;City7&quot;, &quot;60&quot;));
var topThreeDistinct = MyList.Distinct(new StringStringComparer()).OrderByDescending(o =&gt; o.Item2).Take(3).ToList();

var thirdValue = topThreeDistinct[2].Item2;
Console.WriteLine($&quot;Third value = {thirdValue}&quot;);

var topThreeAll = MyList.Where(o =&gt; o.Item2.CompareTo(thirdValue) &gt;= 0 ).ToList();
foreach (var item in topThreeAll)
    Console.WriteLine(item);
Console.WriteLine(&quot;FINISHED&quot;);

class StringStringComparer : IEqualityComparer&lt;(string, string)&gt;
{
    public bool Equals((string, string) x, (string, string) y)
    {
        if (x.Item2 == y.Item2)
        {
            return true;
        }
        else
        {
            return false;
        };
    }

    public int GetHashCode([DisallowNull] (string, string) obj)
    {
        return Convert.ToInt32(obj.Item2);
    }
}

(C# .NET 6.0 Console App)

huangapple
  • 本文由 发表于 2023年4月19日 16:41:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052434.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定