1

現在、データベースクエリの結果である2つのリスト(_pumpOneSpmと_pumpTwoSpm)があります。現在、私はLINQを使用してリストにデータを入力し、計算に使用しています。これに似たもの:

var spmOne = _pumpOneSpm.Where((t, i) => _date[i].Equals(date) &&
            DateTime.Compare(_time[i], DateTime.Parse(start)) > 0 && 
            DateTime.Compare(_time[i], DateTime.Parse(end)) < 0).ToList();

あるリストからデータを取得して特定のデータを別のリストに追加しているので、これは問題ありません。しかし今、私は1つのリストに追加するために2つのリストからデータをプルする必要があります。LINQでこれを行う方法があるのか​​、それともforループで繰り返す必要があるのか​​知りたいのですが。これが私がforループで得たものです:

        for (var i = 0; i < _pumpOneSpm.Count; i++)
        {
            if (_date[i].Equals(date))
            {
                if (DateTime.Compare(_time[i], DateTime.Parse(start)) > 0)
                {
                    if (DateTime.Compare(_time[i], DateTime.Parse(end)) < 0)
                    {
                        spmOne.Add(_pumpOneSpm[i]);
                        spmOne.Add(_pumpTwoSpm[i]);
                    }
                }
            }
        }

これは機能し、私が望むことを実行します。しかし、私はそれをもう少し効率的かつ高速にしようとしています。各リストの最初のコードブロックと同様の2行を使用できますが、それは2回繰り返していることを意味します。それで、私の質問を繰り返すために、LINQコマンドを使用して2つのリストから同時にデータをプルして別のリストにデータを取り込むことは可能ですか、それともforループを使用する必要がありますか?助けてくれてありがとう。

編集

これらのステップを利用する関数の目的は、_pumpOneSpmと_pumpTwoSpmのMAXを微調整することであることに言及しませんでした。それぞれの最大値ではなく、それらの間の最大値。したがって、最初はそれらを1つのリストに追加し、spmOne.Max()を呼び出すだけでした。しかし、上記のような2つのLINQクエリを使用して、ifステートメントを実行して2つの最大値を比較し、2つのうち大きい方を返します。したがって、技術的には、それらが1つのリストに含まれている必要はありません。含まれていると、処理が簡単になると思いました。

4

5 に答える 5

2

したがって、これを行う最も簡単な方法は次のようになります。

var resultList = list1.Concat(list2).ToList();

これはforループとは少し異なることに注意してください(アイテムの順序は同じではありません)。最初のリスト、2番目のリストなどではなく、あるリストのすべてのアイテムとそれに続く別のリストのすべてのアイテムが含まれます。それが重要な場合でも、LINQを使用して実行できますが、さらにいくつかの時間がかかります。メソッド呼び出し。

あなたはパフォーマンスについて言及しました。forループよりもパフォーマンスの面で大幅に向上するわけではないことに注意してください。より短いコードを取得できます。より読みやすく、ほぼ同じように実行されるコード。実行速度の点では、これ以上改善する余地はありません。

2つの方法を組み合わせることができることも注目に値します。それも悪い考えではありません。LINQを使用して2つの入力シーケンスをフィルタリングし(を使用してWhereforeach、結果をフィルタリングしてリストに追加する(またはを使用するAddRange)ことができます。

var query1 = _pumpOneSpm.Where((t, i) => _date[i].Equals(date) &&
            DateTime.Compare(_time[i], DateTime.Parse(start)) > 0 && 
            DateTime.Compare(_time[i], DateTime.Parse(end)) < 0);
var query2 = ...
List<T> results = new List<T>(query1);
results.AddRange(query2);
于 2012-09-19T14:22:28.960 に答える
2

それで、私の質問を繰り返すために、LINQコマンドを使用して2つのリストから同時にデータをプルして別のリストにデータを取り込むことは可能ですか、それともforループを使用する必要がありますか?

リストをマージします。

var mergedList = list1.Union(list2).ToList();

必要に応じて、以下をフィルタリングします。

var filtered = mergedList.Where( p => ... filter ... );

そしてマックスのために:

var max = filtered.Max();

ノート:

OPが言うように、重複しないように注文する必要はないので、ユニオンは大丈夫です。

于 2012-09-19T14:10:54.300 に答える
0

インデックスの使用を避けたい場合は、すべてをまとめて圧縮できます。

spmOne = _pumpOneSpm
          .Zip(_pumpTwoSpm, (pump1, pump2) => new { pump1, pump2 } )
          .Zip(_date, (x, pumpDate) => new { x.pump1, x.pump2, date = pumpDate })
          .Zip(_time, (x, time) => new { x.pump1, x.pump2, x.date, time })
          .Where(x => x.date.Equals(date) &&
                      DateTime.Compare(x.time, DateTime.Parse(start)) > 0 &&
                      DateTime.Compare(x.time, DateTime.Parse(end)) < 0)
          .SelectMany(x => new [] { x.pump1, x.pump2 })
          .ToList();

機能には小さな違いが 1 つあります。シーケンスのいずれかが より短い場合_pumpOneSpm、結果のシーケンスは最短のシーケンスの長さになり、インデックスが範囲外であっても例外はスローされません。

于 2012-09-19T15:57:09.610 に答える
0

SelectMany メソッドを使用できます

http://msdn.microsoft.com/en-us/library/bb548748.aspx

于 2012-09-19T14:12:02.960 に答える
0

Enumerable.Rangeを使用して for ループと同様の機能を実現できます。 SelectManyを使用すると、反復ごとに複数の項目を追加し、結果のシーケンスを平坦化できます。

spmOne = Enumerable
             .Range(0, _pumpOneSpm.Count)
             .Where(index => _date[index].Equals(date) &&
                     DateTime.Compare(_time[index], DateTime.Parse(start)) > 0 &&
                     DateTime.Compare(_time[index], DateTime.Parse(end)) < 0)
             .SelectMany(index => new [] { _pumpOneSpm[index], _pumpTwoSpm[index] })
             .ToList();

クエリ構文のバージョンは次のとおりです。

spmOne = (from index in Enumerable.Range(0, _pumpOneSpm.Count)
          where _date[index].Equals(date) &&
                DateTime.Compare(_time[index], DateTime.Parse(start)) > 0 &&
                DateTime.Compare(_time[index], DateTime.Parse(end)) < 0
          from pumpSpm in new [] { _pumpOneSpm[index], _pumpTwoSpm[index] }
          select pumpSpm).ToList();
于 2012-09-19T15:21:51.843 に答える