使用LINQ在Object中查找Min()的多个实例并更改元素

时间:2013-11-27 15:44:56

标签: c# linq list

我有以下课程;

public class PricePlan
{
    public string Name { get; set; }
    public List<Price> Prices { get; set; }

    public PricePlan()
    {
        Prices = new List<Price>();
    }
}

public class Price
{
    public DateTime Date { get; set; }
    public decimal Rate { get; set; }
    public bool Free { get; set; }

    public Price()
    {
        Free = false;
    }
}

然后填写对象和列表以下内容;

PricePlan oPricePlan = new PricePlan();

oPricePlan.Name = "Standard Rate Plan";

Price oPrice;
DateTime oDate = DateTime.Today;

for (int x = 1; x < 10; x++)
{
   oPrice = new Price();
   oPrice.Date = oDate.AddDays(x);
   oPrice.Rate = 10 * x;
   oPricePlan.Prices.Add(oPrice);
}

oPrice = new Price();
oPrice.Date = oDate.AddDays(11);
oPrice.Rate = 10;
oPricePlan.Prices.Add(oPrice);

示例数据可能是: 02/01/2013,10,False 03/01/2013,20,False 04/01/2013,30,False 05/01/2013,40,False 06/01/2013,50,False 07/01/2013,60,False 08/01/2013,70,False 09/01/2013,80,False 10/01/2013,90,False 12/01/2013,10,False

使用

  

oPricePlan.Prices.Min(r =&gt; r.Rate)

我得到Rate的最小值或者IndexOf []可以返回第一个实例。但是,我想要返回X个最低费率。例如,我如何设置以下内容;

  • 对于系统中的1 Min速率(两个速率可能具有相同的Min),将其设置为0 0并将Free bool设置为true

  • 对于2分钟的费率(可能相同),将其设置为0零并将Free bool设置为true

所以基本上我想找到最低的X个数,改变找到的实际最低费率,并将Free bool标志设置为true。

我应该看看使用LINQ,还是他们的首选方式?

2 个答案:

答案 0 :(得分:1)

int numberOfItems = 1;
var orderedPrices = oPricePlan.Prices.OrderBy(x => x.Rate).ToList();
decimal targetRate = orderedPrices[numberOfItems - 1].Rate;
foreach (var price in orderedPrices.TakeWhile(x => x.Rate <= targetRate))
{
    price.Rate = 0;
    price.Free = true;
}

修改:以上内容基于根据targetRate选择numberOfItems,然后将小于或等于该项的所有项目设置为0(可能是numberOfItems或更多项目)。原来我有:

对于您的示例输入,此代码将选择其中一项费率为10的项目(自oPricePlan.Prices int numberOfItems = 1; foreach (var price in oPricePlan.Prices.OrderBy(x => x.Rate).Take(numberOfItems)) { price.Rate = 0; price.Free = true; } {{1}}起,它将以{{1}}中的第一位出现。 3}})。也就是说,它是项目的数量,而不是不同费率的数量。我认为这就是你所要求的;否则像OrderBy这样的解决方案是正确的。

{{1}}

答案 1 :(得分:0)

您可以使用OrderBy + GroupByTake和循环:

var priceGroups = oPricePlan.Prices
    .OrderBy(p => p.Rate)  // order by rate ascending
    .GroupBy(p => p.Rate)  // group by rate
    .First()  // use the lowest price-rate group only
    .Take(2); // change 2 to 1 if you only want to modify one price in this min-group

foreach (Price price in priceGroups)
{
    price.Rate = 0;
    price.Free = true;
}