C# 查询嵌套字典

C# 查询嵌套字典,c#,linq,dictionary,C#,Linq,Dictionary,我很好奇是否有人能有效地解决这个问题。我目前拥有以下对象 Dictionary<int, Dictionary<double, CustomStruct>> struct CustomStruct { double value1; double value2; ... } 字典 结构自定义结构 { 双值1; 双重价值2; ... } 鉴于我知道要访问的“int”,我需要知道如何为具有最低总和(value1+value2)的字典返回“doubl

我很好奇是否有人能有效地解决这个问题。我目前拥有以下对象

Dictionary<int, Dictionary<double, CustomStruct>>

struct CustomStruct
{
    double value1;
    double value2;
    ...
}
字典
结构自定义结构
{
双值1;
双重价值2;
...
}
鉴于我知道要访问的“int”,我需要知道如何为具有最低总和(value1+value2)的字典返回“double key”。任何帮助都将不胜感激。我试图使用Linq,但任何方法都会被感激

var result = dict[someInt].MinBy(kvp => kvp.Value.value1 + kvp.Value.value2).Key;
使用awesome项目中的。仅使用普通LINQ:

Dictionary<int, Dictionary<double, CustomStruct>> dict = ...;
int id = ...;

var minimum =
   (from kvp in dict[id]
    // group the keys (double) by their sums
    group kvp.Key by kvp.Value.value1 + kvp.Value.value2 into g
    orderby g.Key          // sort group keys (sums) in ascending order
    select g.First())      // select the first key (double) in the group
   .First();               // return first key in the sorted collection of keys
Dictionary dict=。。。;
int id=。。。;
最小值=
(来自dict[id]中的kvp)
//按键的和对键进行分组(双倍)
按kvp.Value.value1+kvp.Value.value2将kvp.Key分组为g
orderby g.Key//按升序对组键(和)排序
选择g.First())//选择组中的第一个键(双精度键)
.First();//返回已排序的键集合中的第一个键
每当您想要使用普通LINQ获取最小或最大项时,通常必须使用组合的
GroupBy()
OrderBy()
First()
/
Last()
来获取它。

字典
也是一个
键值对序列。您可以选择值和最少的KeyValuePair,并获取其密钥

对对象使用纯LINQ:

dict[someInt].OrderBy(item => item.Value.value1 + item.Value.value2)
             .FirstOrDefault()
             .Select(item => item.Key);

这是非LINQ方式。它不比LINQ的同类产品短,但效率更高,因为它不像大多数LINQ解决方案那样进行排序,如果收集量很大,可能会变得很昂贵

来自dtb的MinBy解决方案是一个不错的解决方案,但它需要一个外部库。我非常喜欢LINQ,但有时您应该提醒自己,带有几个局部变量的foreach循环不是过时的或错误的

CustomStruct Min(Dictionary<double, CustomStruct> input)
{
    CustomStruct lret = default(CustomStruct);
    double lastSum = double.MaxValue;

    foreach (var kvp in input)
    {
        var other = kvp.Value;
        var newSum = other.value1 + other.value2;
        if (newSum < lastSum)
        {
            lastSum = newSum;
            lret = other;
        }
    }
    return lret;
}
CustomStruct最小值(字典输入)
{
CustomStruct lret=默认值(CustomStruct);
double lastSum=double.MaxValue;
foreach(输入中的var kvp)
{
var other=千伏值;
var newSum=other.value1+other.value2;
if(newSum
如果要使用LINQ方法而不使用外部库,可以创建自己的MinBy,如下所示:

public static class Extensions
{
    public static T MinBy<T>(this IEnumerable<T> coll, Func<T,double> criteria)
    {
        T lret = default(T);
        double last = double.MaxValue;
        foreach (var v in coll)
        {
            var newLast = criteria(v);
            if (newLast < last)
            {
                last = newLast;
                lret = v;
            }
        }
        return lret;
    }

}
公共静态类扩展
{
公共静态T MinBy(此IEnumerable coll,Func条件)
{
T lret=默认值(T);
double last=double.MaxValue;
foreach(coll中的v值)
{
var newLast=标准(v);
if(newLast

它的效率不如第一个,但它完成了任务,并且比第一个更具可重用性和可组合性。使用Aggregate的解决方案具有创新性,但需要重新计算与当前最佳匹配项进行比较的每个项的当前最佳匹配项的总和,因为在聚合调用之间没有足够的状态

谢谢大家的帮助,我也是这样发现的:

dict[int].Aggregate(
                    (seed, o) =>
                        {
                            var v = seed.Value.TotalCut + seed.Value.TotalFill;
                            var k = o.Value.TotalCut + o.Value.TotalFill;
                            return v < k ? seed : o;
                        }).Key;
dict[int]。聚合(
(种子,o)=>
{
var v=seed.Value.TotalCut+seed.Value.TotalFill;
var k=o.Value.TotalCut+o.Value.TotalFill;
返回v
不要贪心,因为从MoreLINQ上的文档来看,这正是我需要的。。。但是,有没有其他方法可以在不使用MoreLINQ项目的情况下有效地做到这一点呢?感谢所有的帮助人员,也找到了这种方法:dict[someInt].Aggregate((seed,o)=>{var v=seed.Value.value1+seed.Value.value2;var k=o.Value.value1+o.Value.value2;返回v