2016-05-13 7 views
0

私はこれらの車のリストとその車のリストを持っています。すべてのレンタルはDateTime FromDateTime ToCar Carです。リストの要素を別のリストの値に基づいて効率的にフィルタリングする方法

私は、選択した期間に利用できない車のリストから除外したいと思います。この期間の始めと終わりは、2つの値、つまりDateTimePickersです。

私はこのコードで私の目標を達成しました:

public void FilterAvailableCars() {    
      List<Car> cars = ObjectPlus.Objects[typeof(Car)].Select(o => (Car)o).ToList();    
      List<Rental> rentals = ObjectPlus.Objects[typeof(Rental)].Select(r => (Rental)r).ToList();   
      foreach (var rent in rentals) { 
       if (fromDateTimePicker.Value < rent.To && rent.From < toDateTimePicker.Value) { 
        cars.Remove(rent.Car); 
       }    
      } 
      carListBox.DataSource = cars;    
     } 

私は、LINQを混合し、forループが、私はLINQのソリューションは次のようになりますどのように純粋かつ効率的に知っていただきたいと思います。

+0

あなたは、LINQのを理解しているように見えるので、私はあなたが持つ難しさを持っているかが不明です。あなたはLinqの 'Where'に精通していますか?それとも効率的な質問ですか? – Ulric

+0

すべての関数をlinqに変換しないでください。あなたのコードは簡単に理解できるはずです。複雑なlinqステートメントは、コードを維持しにくいものにします。現在のソリューションを変更する必要はありません。 – jdweng

答えて

1

まず、あなたの条件に基づくすべてのレンタカーを選択します。

var rentalCars = rentals.Where(rent => 
        fromDateTimePicker.Value < rent.To && rent.From < toDateTimePicker.Value) 
     .Select(r => r.Car); 

その後、結果を取得するためにExceptメソッドを使用します。

+0

Sinatr postよりも私の解答はより効率的ですか? Sinatrの答えから訂正されたコードです。 – Yoda

+0

@Yoda:はい、あなたのコメント付きコードはより効率的です。 –

1

少数の修正:

// filter rentals within entered date 
var rentals = ObjectPlus.Objects[typeof(Rental)].Cast<Rental>() 
    .Where(rent => fromDateTimePicker.Value < rent.To && rent.From < toDateTimePicker.Value); 
// filter rented cars 
carListBox.DataSource = ObjectPlus.Objects[typeof(Car)].Cast<Car>() 
    .Where(car => !rentals.Any(rent => rent == car)).ToList(); 

Cast/OfTypeを使用し、Whereを1つ使用してフィルタリングします(あなたがそうしているように項目をリストしたり削除したりするのは非効率的です)。

Exceptの効率性がわかりません。クエリ結果をインスタンス化しないと(ToList()を使用した場合)、同じ効率である必要があります。

レンタルのWhereの中の車をチェックする方が効率的です(RentalCarの項目の数によります)。

+0

これは修正されたコードです。 'public void FilterAvailableCars(){ var rentals = ObjectPlus.Objects [typeof(Rental)]。キャスト(); carListBox.DataSource = ObjectPlus.Objects [typeof(Car)]キャスト() .Where(car =>!rentals.Any(rent => rent.Car == car && fromDateTimePicker.Value Yoda

+0

右は編集を参照してください。 'ToList()'がレンタルされている方が良いとは思いません(より多くのメモリが必要ですが、より速くなります)。 – Sinatr

1

最も効率的な方法は、通常、(あなたのケースのようにまたはantijoinjoinを使用してデータを相関させることである。

var rentals = ObjectPlus.Objects[typeof(Rental)].Cast<Rental>() 
    .Where(rent => fromDateTimePicker.Value < rent.To && rent.From < toDateTimePicker.Value); 
carListBox.DataSource = 
    (from car in ObjectPlus.Objects[typeof(Car)].Cast<Car>() 
    join rent in rentals on car equals rent.Car into carRentals 
    from carRent in carRentals.DefaultIfEmpty() 
    where carRent == null 
    select car).ToList(); 
関連する問題