0

プロジェクト内の既存のコードをlinq呼び出しに置き換えて、linqを学習しようとしています。このメソッドでは、行のリストで条件を確認し、条件がtrueの場合は、その要素を行からprocessedLinesに移動します。

データ構造は単なるリストです。

List<LineSegment2> lines;
List<LineSegment2> processedLines;

元のコードは次のとおりです。

for (int i = lines.Count - 1; i >= 0; i--)
{           
   if (lines[i].P2.x < sweepPosition)
   {
      processedLines.Add(lines[i]);
      lines.RemoveAt(i);
   }
}

私のlinqコードは次のとおりです。

var toMove = lines.FindAll(x => x.P2.x < sweepPosition);
toMove.ForEach(x =>
{
   processedLines.Add(x);
   lines.Remove(x);
});

私の質問は次のとおりです。このlinqコードは、一時リスト'toMove'を作成するためにより多くのメモリを使用しているため、効率が低下しますか。一時リストを必要とせずにlinqクエリを作成する方法はありますか、それとも元のコードの方が常に効率的ですか?

4

3 に答える 3

1

よりLINQyの解決策は、処理されたすべての行を一度に追加してから、残りの行を取得することです。

processedLines.AddRange(lines.Where(x => x.P2.x < sweepPosition));
lines = lines.Where(x => x.P2.x >= sweepPosition).ToList();

効率に関しては、元のコードほど速くはありません。それが、LINQを使用する理由ではありません。

ただし、潜在的な利点が1つあります。新しい行のリストが作成されるため、処理済みのリストに多くの行を移動すると、リスト内の未使用のアイテムが削除されます。

于 2012-06-12T07:06:27.283 に答える
1

「linq」コードは効率が低く、(さらに重要なことに)必ずしも保守がはるかに簡単であるとは限りません。これらの2つの選択肢から選択する必要がある場合は、元のコードを使用してください。ループを順方向に実行することをお勧めしますfor。実行しているように逆方向に実行する必要がある理由はありません。

ちなみに、ユースケースで単一のリストを維持し、クラスIsProcessedにプロパティを追加するのが適切かどうか疑問に思います。LineSegment2あなたはそれを考えるかもしれません。

于 2012-06-12T07:28:00.750 に答える
0

効率についてはよくわかりませんが、Linqではこのようにします

processedLines = processedLines.Concat(lines.Where(x => x < sweepPosition)).ToList();
lines.RemoveAll(x => x < sweepPosition);
于 2012-06-12T07:04:50.283 に答える