比较两个字典并使用 Linq 确定最小值
Posted
技术标签:
【中文标题】比较两个字典并使用 Linq 确定最小值【英文标题】:Compare two dictionaries and determine the minimum value using Linq 【发布时间】:2020-03-11 23:08:56 【问题描述】:我正在尝试找出一种方法来使用 Linq 将两个字典相互比较,并确定 DictB
中来自 DictA
的键的最小值。
假设两个字典上的键都是代表用户及其分数的唯一 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 确定最小值的主要内容,如果未能解决你的问题,请参考以下文章
比较两个列表并选择最大值和最小值。 (float 不是可迭代对象)