【问题标题】:Compare two dictionaries and determine the minimum value using Linq比较两个字典并使用 Linq 确定最小值
【发布时间】:2020-03-11 23:08:56
【问题描述】:

我正在尝试找出一种方法来使用 Linq 将两个字典相互比较,并确定 DictB 中来自 DictA 的键的最小值。

DictA:{ 1,“罗恩”},{ 3,“爱丽丝”} 字典:{ 1, 9 }, { 2, 7 }, { 3, 10 }, { 4, 8 }, { 5, 12 }

假设两个字典上的键都是代表用户及其分数的唯一 ID,我希望能够确定在 DictA 的用户中得分最低的用户,即用户 @987654324 @ ("Ron") 得分为 9。

我假设它必须是这样的:

var pLoser = DictA[
    DictB
        .Where(x => DictA.ContainsKey(x.Key))
        .Aggregate((l, r) => l.Value < r.Value ? l : r)
        .Key
    ];

我想知道这是否是实现我想要的正确方法,或者是否有更好的方法。

【问题讨论】:

  • 除非您能够非常明确地定义“正确”和“更好”对您意味着什么,否则无法回答包含“正确”和“更好”等词的问题。
  • 第 1 步:通过选择更好的数据结构来帮助自己。

标签: c# linq dictionary lookup min


【解决方案1】:

我想我会这样做——可能会更快,但似乎最好——按值排序检查它是否存在并取第一个:

var pLoser = DictA[
  DictB
    .OrderBy(x => x.Value) // lowest values first
    .Where(x => DictA.ContainsKey(x.Key))
    .FirstOrDefault()
    .Key
];

这应该利用 linq 的惰性特性来做最少的工作来解决问题。

【讨论】:

    【解决方案2】:

    似乎join 是这里的自然解决方案:

    var lowestScore = 
        (from a in dictA
        join b in dictB on a.Key equals b.Key
        orderby b.Value
        select new {Name = a.Value, Score = b.Value}).First()
    

    【讨论】:

      【解决方案3】:

      一种方法是使用 Join,然后将结果投影到具有一些常识属性名称的匿名类型,然后按分数排序并取第一个返回值。这假设总会有一个返回值,但如果并非总是如此,您也可以使用FirstOrDefault 而不是First

      var lowestScore = DictA.Join(DictB, entryA => entryA.Key, entryB => entryB.Key, (entryA, entryB) => new {Id = entryA.Key, Name = entryA.Value, Score = entryB.Value})
          .OrderBy(x => x.Score)
          .First();
      

      请注意,如果最后一名有竞争分数,并且您想返回所有分数,那么使用 GroupBy 会更有意义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多