【问题标题】:Select from array only the best items仅从数组中选择最佳项目
【发布时间】:2014-11-19 14:44:52
【问题描述】:

我正在努力想出一个 linq 语句,我想只选择数组中具有最高版本的一些项目。 给定一组应用程序,例如:

[{name="Adobe", version=1},
{name="Adobe", version=2},
{name="Adobe", version=3},
{name="VLC", version=1},
{name="VLC", version=2},
{name="VLC", version=3}]

我需要一个 linq 来仅选择 1 个 adobe 应用程序、最高版本的应用程序和 1 个 VLC 应用程序。 结果应如下所示:

[{name="Adobe", version=3},
{name="VLC", version=3}]

到目前为止我得到的最好的是:

var names = apps.Select((n => n.name)).Distinct();
foreach (var name in names)
{
    var latest = apps.Where(n => n.name == name).OrderByDescending(n => n.version).FirstOrDefault();
    //add latest to the new appList
}

我一直在思考是否有更简单的、仅 linq 的方法来做到这一点。有什么建议吗?

谢谢。

【问题讨论】:

  • 欢迎来到 StackOverflow!请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”。
  • 如果有另一个应用程序(“记事本”)版本为 1-4,您希望发生什么?您还想要 Adob​​e 和 VLC v3 吗?
  • 你知道Version类吗?

标签: c# arrays linq sorting


【解决方案1】:

你可以试试这样的:

var latest = apps.GroupBy(x=>x.name)
                 .Select(x=> new 
                 { 
                     Name=x.Key, 
                     Version = x.OrderByDescending(y=>y.version)
                                .First().version
                 });

最初,我们将GroupBy 作为应用程序的名称。然后我们选择每个组的项目,最新版本。

【讨论】:

  • 最后我想你想要.First().version
  • 如果您需要包含另一个属性...例如 ReleaseDate 或 DownloadSize 属性怎么办?
  • 你能不做 Version = x.Max(y => y.version) 吗?
  • 琼斯是对的。就像现在一样,它要求 version 为 true 的第一项,这意味着它不应该编译,因为 version 不是布尔值。
  • @TimSchmelter 他想要的输出看起来与他的输入相同
【解决方案2】:

这是一个更简单的方法:

var latest = apps.GroupBy(i => i.Name)
                 .Select(i => i.OrderByDescending(j => j.Version).First());

【讨论】:

  • Too late ;-) 它也不是更简单,而是不同。
  • @tim-schmelter 多哈!你公平地打败了我。 (我只是想达到 15 个,这样我才能投票选出正确的答案。)
【解决方案3】:

这是我的看法:

void Main()
{
    var apps = new NameVersion[]
    {
        new NameVersion {name="Adobe", version=1},
        new NameVersion {name="Adobe", version=2},
        new NameVersion {name="Adobe", version=3},
        new NameVersion {name="VLC", version=1},
        new NameVersion {name="VLC", version=2},
        new NameVersion {name="VLC", version=3}
    };


    var q = from a in apps
            group a by a.name into g
            select new NameVersion { name=g.Key, version = g.Max(a=> a.version)};

    q.Dump();
}

【讨论】:

    【解决方案4】:

    你可以使用Enumerable.GroupBy:

    IEnumerable<SomeClass> latest = apps
        .GroupBy(n => n.name)
        .Select(nameGroup => nameGroup.OrderByDescending(n => n.version).First());
    

    【讨论】:

      【解决方案5】:

      对于带 Max() 和不带 (Select+GroupBy()) 的小型集合:

      var list = apps.ToList();
      var res = list.Where(
                          x => list.Where(elem=>elem.name == x.name)
                                   .Max(elem=>elem.version) == x.version);
      

      【讨论】:

        猜你喜欢
        • 2022-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-08
        • 2013-12-16
        • 2011-11-10
        • 2014-07-15
        相关资源
        最近更新 更多