2015-07-28 6 views
1
var filterModel = new List<FilterModel>() 
{ 
    new FilterModel {Price = 1}, 
    new FilterModel {Price = 1},     
    new FilterModel {Price = 15}, 
    new FilterModel {Price = 20}, 
    new FilterModel {Price = 410}, 
    new FilterModel {Price = 9511}, 
    new FilterModel {Price = 9511}, 
    new FilterModel {Price = 252}, 
    new FilterModel {Price = 555}, 
    new FilterModel {Price = 602} 
}; 

var priceList = new List<PriceList> 
{ 
    new PriceList{MinPrice = 0,MaxPrice = 30}, 
    new PriceList{MinPrice = 70,MaxPrice = 130}, 
    new PriceList{MinPrice = 200,MaxPrice = 250}, 
    new PriceList{MinPrice = 400,MaxPrice = 600}, 
    //etc.etc. continue... 
}; 

У меня есть 2 модели. Я пытаюсь использовать LINQ. Мой код работает. Что было бы самым коротким (самым чистым) способом сделать это?Использование linq позволяет выбрать несколько значений цен

var newFilterModel = new List<FilterModel>(); 

foreach (var t in priceList) 
{ 
    newFilterModel.AddRange(filterModel 
           .Where(x => x.Price > t.MinPrice && x.Price < t.MaxPrice) 
           .ToList()); 
} 
var distinctNewFilterModel = newFilterModel.Select(p=>new { p.Price}) 
              .Distinct().ToList(); 
+1

что вы имеете в виду _shortes (самый чистый) путь_? – Grundy

+0

Не использовать foreach, если это возможно. – user3583183

+0

вы можете использовать [предложение соединения] (https://msdn.microsoft.com/en-us/library/bb311040.aspx) и [это] (https://msdn.microsoft.com/en-us/library/ bb882533.aspx) – Grundy

ответ

2

Я не знаю, если это короткий & достаточно чистый для вас, но ...

var newFilterModel = filterModel 
    // Select just the price 
    .Select(f => f.Price) 
    // Remove duplicates 
    .Distinct() 
    // Find prices in the price list 
    .Where(price => priceList 
     .FindIndex(p => p.MinPrice <= price && price <= p.MaxPrice) != -1) 
    // Turn the price back into a FilterModel object 
    .Select(price => new FilterModel { Price = price }) 
    // Turn the entire result into a new List<FilterModel> 
    .ToList(); 

newFilterModel.ForEach(newF => Console.WriteLine(newF.Price)); 

Результаты:

1 
15 
20 
410 
555 

Если вы должны были реализовать IEquatable<> в вашем FilterModel классе, как это:

public class FilterModel : IEquatable<FilterModel> 
{ 
    public int Price { get; set; } 

    public bool Equals(FilterModel other) 
    { 
     //Check whether the compared object is null. 
     if (ReferenceEquals(other, null)) return false; 

     //Check whether the compared object references the same data. 
     if (ReferenceEquals(this, other)) return true; 

     //Check whether the products' properties are equal. 
     return other.Price == Price; 
    } 

    public override int GetHashCode() 
    { 
     //Get hash code for the Price field. 
     return Price.GetHashCode(); 
    } 
} 

Тогда ваш Linq утверждение становится короче:

var newFilterModel = filterModel 
    // Remove duplicates 
    .Distinct() 
    // Find prices in the price list 
    .Where(filterPrice => priceList 
     .FindIndex(price => price.MinPrice <= filterPrice.Price && filterPrice.Price <= price.MaxPrice) != -1) 
    // Turn the entire result into a List<FilterModel> 
    .ToList(); 

newFilterModel.ForEach(p => Console.WriteLine(p.Price)); 

Результаты:

1 
15 
20 
410 
555 
1

Вы можете использовать cross join как это и получить IEnumerable<FilterModel>

var distinctNewFilterModel = from filter in filterModel 
          from price in priceList 
          where filter.Price > price.MinPrice && filter.Price < price.MaxPrice 
          group filter by filter.Price into groupped 
          select groupped.First(); 

, но не уверен, что это кратчайшее и чистейший чем вы