比较两个字典并使用 Linq 确定最小值

Posted

技术标签:

【中文标题】比较两个字典并使用 Linq 确定最小值【英文标题】:Compare two dictionaries and determine the minimum value using 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 步:通过选择更好的数据结构来帮助自己。 【参考方案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 会更有意义。

【讨论】:

以上是关于比较两个字典并使用 Linq 确定最小值的主要内容,如果未能解决你的问题,请参考以下文章

在数组中查找最小值和最大值

java中如何找出一串时间序列中的最大,最小值

比较两个列表并选择最大值和最小值。 (float 不是可迭代对象)

mysql 多表查询 比较两个字段最大、最小值,并显示对应字段

使用 Linq 仅选择最小值

不使用 max() 和 min() 从字典中获取最大值和最小值