4

私自身、LINQの大ファンです。簡潔さの芸術はLINQに反映されています。また、.Netでは、LINQはループの一歩先を行っている、またはLINQはループ++であると言えます。

しかし、それは本当にこの方法ですか?

私が判断力を持っているのは、このforループコードをLINQに変換しようとしたが、LINQがインデックスをスキップ/残すと混乱したためです。

double[] NMD = {3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0 };

for(int i=1; i<NMD.Length-1; i+=2)
   NMD[i] = NMD[i]/10;

ここでは、ループをインデックス1から開始し、最後から2番目の値で停止し、値を2スキップするように要求しています。LINQでこれを実行できますか。IMOそうは思いませんが、間違っていることが証明されてうれしいです。

4

4 に答える 4

5

内部のインデックスをテストし、Selectそれに応じてアクションを選択できます。

NMD = NMD.Select((x, i) => i % 2 == 1 && i < NMD.Length - 1 ? x / 10 : x).ToArray();
// => { 3, 0.5, 6, 6.5, 34, 0.3, 5, 0.6, 65, 3.4, 3, 0.5, 6, 6.5, 34 }

ただし、このステートメントのサイズを見てすでに理解しているかもしれませんが、LINQを使用して新しいシーケンスを作成することしかできず、既存のシーケンスを変更することはできないため、ここではLINQは概念的な改善ではありません

そうは言っても、for私の意見では、ループは問題なく、実際にはより読みやすくなっています。「LINQisloops++」と言うのではなく、「LINQ issequencegeneration++」または「read-onlyiteration++」に改良する必要があります。

LINQを効率的に使用する場合は、すべてのforループをLINQ式に置き換えるだけでなく、コードをより機能的な方法で再考および再設計する必要があります(たとえば、不変のデータ構造を使用します)。結果として賢明にそれを行うと、コードの品質を向上させ、将来的にスイッチの並列実行の問題を減らすことができます。

于 2012-04-21T10:40:18.537 に答える
1
var NMD = new[] {3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0 };
NMD = NMD.Select((n, i) => i % 2 == 1  ? n / 10 : n).ToArray();
于 2012-04-21T10:41:53.387 に答える
0

インデックスが奇数のアイテムのみを選択できますNMD.Where((x,i) => i % 2 == 1)が、配列の値を更新することはできません。

于 2012-04-21T10:38:15.180 に答える
0

Linqは、この種のタスクに最適なツールではありません。データをインプレースで変更するのは、その一部にすぎません。しかし、本当にやりたいのであれば、次のように行うことができます。

NMD = NMD.Select((x, i) =>
{
    if (i < 1 || i >= NMD.Length - 1 || (i % 2)==0)
        return x;
    else
        return x / 10;
}).ToArray();

linqでは、既存のシーケンスを変更せず、新しいシーケンスに置き換えることを忘れないでください。

于 2012-04-21T10:45:08.327 に答える