4

皆さんこんにちは、

今日は、お気に入りの C# ヘルプ リソース Web サイトへの最初の投稿です。コミュニティに参加できてうれしいです。

これが私の問題です.Where句でdouble値のリストをフィルタリングした後、.Select linq句を呼び出して構造体のリストを作成したいと思いますが、フィルタリング条件が評価されていないように見えるか、常にtrueを返します。
問題をよく理解するために私のコードを見てください:

string[] msgNames = new string[] { "de", "vf", "ze", "ki", "vt", "er" };
double[] prevCounters = new double[] { 154.0, 24588.0, 4547.0, 788.0, 1455.0, 24577.0 };
double[] counters = new double[] { 8548.0, 54854.0, 54854.0, 44.0, 121.0, 48547.0 };
double[] lenValues = new double[] { 1.0, 2.0, 0.0, 4.0, 5.0, 0.0 };

BufferInfo[] positiveLenValues = counters
    .Where((c, it) => lenValues[it] >= 1.0 && prevCounters[it] != c)
    .Select((c, it) =>
    {
        prevCounters[it] = c;

        return new BufferInfo()
        {
            Name = msgNames[it],
            Length = lenValues[it]
        };
    }).ToArray();

おそらく私は linq の使用法を誤解していましたが、返された BufferInfo[] には最後にすべての値が含まれていますが、lenValues 配列には 1.0 未満の値がいくつかあります。詳細については、このコード ブロックへの同時アクセスはありません。.linq ブロックのローカル変数は通常、動的にインスタンス化されます (ナショナル インスツルメンツの外部アセンブリによって返されます)。

たとえば、同じ動作ですが、for ループを使用しても同様に機能します。

List<BufferInfo> myInfos = new List<BufferInfo>();

for (int i = 0; i < 6; i++)
{
    if (lenValues[i] >= 1.0 && prevCounters[i] != counters[i])
    {
        oldCounters[i] = counters[i];
        myInfos.Add(new BufferInfo()
                    {
                        Length = lenValues[i],
                        Name = msgNames[i]
                    });
    }
}

BufferInfo[] buffers = myInfos.ToArray();

linq を使用するかどうかは気にしません。失敗する理由を理解したいだけです。
これらの奇妙な結果が得られた理由を説明してください。


Lun@ir さん、よろしくお願いします。

4

2 に答える 2

1

あなたのコードはコンパイルさえしないので、それが機能しないことをどのようにテストしたのかわかりません...

Select最初にインデックスを取得するように記述してから、Whereメソッドに渡す必要があります。

BufferInfo[] positiveLenValues = counters.Select((c, i) => new { c, i })
                                         .Where(e => lenValues[e.i] >= 1.0 && prevCounters[e.i] != e.c)
                                         .Select(e =>
                                         {
                                             prevCounters[e.i] = e.c;
                                             return new BufferInfo
                                             {
                                                 Name = msgNames[e.i],
                                                 Length = lenValues[e.i]
                                             };
                                         }).ToArray();

そのコードは4つの値を返します。これは予測可能で、正しい結果のようです。

于 2013-03-08T16:49:36.630 に答える