2

この質問を説明するのは少し難しいですが、簡単に説明しようと思います。

このようなキーと値のペアのコレクションがある状況があります。

class Foo {
   int Number { get; set; }
   int Value { get; set; }
}

それで、私はこのようにコレクションを設定します...

var collection = new List<Foo>{
   new Foo { Number = 1, Value = 1 },
   new Foo { Number = 2, Value = 2 },
   new Foo { Number = 3, Value = 3 },
   new Foo { Number = 4, Value = 4 }
};

したがって、基本的に、以前のすべての値の合計が特定の値以下である数値を見つけられるようにしたいと考えています。例えば ​​...

値が 3 の場合、返される Number は になりますcollection[1]。(collection[0]の値は 1 で、collection[1]値は 2 で、合計すると 3 になります)

いくつかの異なる行を使用してこれを実現できますが、LINQ がより簡潔な方法でそれを実行できるかどうか疑問に思っていました。

4

4 に答える 4

1

いいえ、LINQ はこれには適していません。可能ですが、基本的には関数を使用してAggregate、独自の集計作成デリゲートを提供する必要があります。これを行う方がはるかに簡単です(理解しやすいことは言うまでもありません):

int sum = 0;

foreach(var item in collection)
{    
    sum += item.Value;

    if (sum >= targetValue) return item;
}

return null;
于 2012-07-14T04:59:18.767 に答える
0

LINQは通常、要素間の相互依存性を促進しません(この場合、各要素は、その前の要素の合計に対する可視性を必要とします)。

これを行うためのループを作成する方がはるかに簡単で明確です。機能的な感触を保つために、拡張メソッドの後ろに置くことができます。

public static Foo FirstBeyondSum(this IEnumerable<Foo> source, int value)
{
    var sum = 0;

    foreach(var item in source)
    {
        sum += item.Value;

        if(sum >= value)
        {
            return item;
        }
    }

    return null;
}

使用法:

var firstFooBeyond3 = foos.FirstBeyondSum(3);
于 2012-07-14T05:09:54.907 に答える
0

LINQはこれには適していないと人々があなたに言い続けた理由はわかりません...

    var sum = 0;
    return collection.FirstOrDefault(item => (sum += item.Value) >= targetValue);

エッジケースによっては >= の代わりに > かもしれませんが、アイデアはわかります...

または:

return collection.FirstOrDefault(item =>
    {
        sum += item.Value;
        return (sum += item.Value) >= targetValue;
    });

(sum += item.Value) >= targetValue ハックが気に入らない場合は...

于 2012-07-14T05:34:40.660 に答える
0

正確な質問は次のとおりです。

いくつかの異なる行を使用してこれを達成できますが、LINQ がより簡潔な方法でそれを実行できるかどうか疑問に思っていました。

OPはLINQを使用しないことでこの問題をすでに解決しており、より優れたLINQソリューションがあるかどうか疑問に思っています。そのため、LINQ を使用しないよりも問題を解決できるかどうかを評価できるように、LINQ ソリューションを確認したいと考えています。

したがって、問題に対するLINQソリューションとして私が思いつくことができる最高のものは次のとおりです。彼のコードよりも効率が悪いことが判明したとしても、LINQ がそれをより簡潔に実行できるかどうかという彼の質問に対する答えであり、彼の正確な質問に答えることができます。

また、OP が LINQ を使用するかどうかを評価できる最善の方法は、例を示すことです。彼が LINQ を使用できなかった理由がわかりません。

コレクションからアイテムを取得するには:

var item = collection
    .Where((f,i) => value >= collection.Take(i + 1).Sum (c => c.Value))
    .Last();

代わりにそのアイテムのインデックスを探している場合:

var index = collection.IndexOf(
     collection.Where((f,i) => value >= collection.Take(i + 1).Sum (c => c.Value))
    .Last());
于 2012-07-14T18:16:34.400 に答える