4

誰かがこの問題を効率的に解決する良い方法を持っているかどうか私は興味がありました。私は現在、次のオブジェクトを持っています。

Dictionary<int, Dictionary<double, CustomStruct>>

struct CustomStruct
{
    double value1;
    double value2;
    ...
}

アクセスしたい「int」がわかっているので、(value1 + value2)の合計が最小の辞書の「doublekey」を返す方法を知る必要があります。どんな助けでも大歓迎です。私はLinqを使おうとしていましたが、どんな方法でもいただければ幸いです。

4

5 に答える 5

4
var result = dict[someInt].MinBy(kvp => kvp.Value.value1 + kvp.Value.value2).Key;

すばらしいMoreLINQプロジェクトのMinBy 拡張メソッドを使用します。

于 2012-05-02T20:52:01.147 に答える
1

単純な 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

通常の LINQ を使用して最小または最大の項目を取得する場合は、通常GroupBy()OrderBy()First()/の組み合わせを使用Last()して取得する必要があります。

于 2012-05-02T21:37:45.860 に答える
1

ADictionary<TKey,TValue>も のシーケンスですKeyValuePair<TKey,TValue>。値の合計が最小の KeyValuePair を選択して、そのキーを取得できます。

オブジェクトへの純粋な LINQ の使用:

dict[someInt].OrderBy(item => item.Value.value1 + item.Value.value2)
             .FirstOrDefault()
             .Select(item => item.Key);
于 2012-05-02T21:38:50.533 に答える
0

すべての助けてくれてありがとう、この方法も見つけました:

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;
于 2012-05-03T12:54:19.663 に答える
0

これが非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;
}

extern ライブラリを使用せずに 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;
    }

}

最初のものほど効率的ではありませんが、最初のものよりも再利用可能で構成可能です。Aggregate を使用したソリューションは革新的ですが、集約呼び出し間で十分な状態を保持していないため、現在の最適一致が比較されるすべての項目について、現在の最適一致の合計を再計算する必要があります。

于 2012-05-02T22:22:57.343 に答える