score:4

Accepted answer
var result = dict[someint].minby(kvp => kvp.value.value1 + kvp.value.value2).key;

using the minby extension method from the awesome morelinq project.

score:0

here is the non linq way. it is not shorter than its linq counterparts but it is much more efficient because it does no sorting like most linq solutions which may turn out expensive if the collection is large.

the minby solution from dtb is a good one but it requires an external library. i do like linq a lot but sometimes you should remind yourself that a foreach loop with a few local variables is not archaic or an error.

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;
}

if you want to use the linq method without using an extern library you can create your own minby like this one:

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;
    }

}

it is not as efficient as the first one but it does the job and is more reusable and composable as the first one. your solution with aggregate is innovative but requires recalculation of the sum of the current best match for every item the current best match is compared to because you carry not enough state between the aggregate calls.

score:0

thanks for all the help guys, found out this way too:

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;

score:1

using just plain 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

whenever you want to get the minimum or maximum item using plain linq, you usually have to do it using ith a combination of groupby(), orderby() and first()/last() to get it.

score:1

a dictionary<tkey,tvalue> is also a sequence of keyvaluepair<tkey,tvalue>. you can select the keyvaluepair with the least sum of values and and get its key.

using pure linq to objects:

dict[someint].orderby(item => item.value.value1 + item.value.value2)
             .firstordefault()
             .select(item => item.key);

Related Query

More Query from same tag