【问题标题】:Use LINQ To find multiple instances of Min() in Object and change the element(s)使用 LINQ 在 Object 中查找 Min() 的多个实例并更改元素
【发布时间】:2018-11-15 01:41:41
【问题描述】:

我有以下课程;

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 => r.Rate)

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

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

  • 对于 2 Min rate(可能相同),将其设置为 0 零并将 Free bool 设置为 true

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

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

【问题讨论】:

  • 包括示例输出以澄清您的问题。我得出了与另一个回答者不同的结论。

标签: c# linq list


【解决方案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;
}

编辑:以上是基于numberOfItems选择一个targetRate,然后将所有小于或等于0的项目设置为0(可能是numberOfItems或更多项目)。最初我有:

对于您的示例输入,此代码将选择比率为10 的项目之一(它将是oPricePlan.Prices 中最先出现的项目,因为OrderBystable)。也就是说,它是 items 的数量,而不是不同 rate 的数量。我认为这就是您所要求的;否则像Tim Schmelter's 这样的解决方案是正确的。

int numberOfItems = 1;
foreach (var price in oPricePlan.Prices.OrderBy(x => x.Rate).Take(numberOfItems))
{
    price.Rate = 0;
    price.Free = true;
}

【讨论】:

  • 在示例中最便宜的价格是 10,所以我希望它们都设置为 0(在 02/01/2013 和 12/01/2013)。
  • 好的,如果您想删除 2 最低费率而不是 1,这是否意味着 1020 或两者都 10s?
  • 如果我更改了 numberOfItems,我想采用两个最低费率。在示例中是 10 和 10。但也可以是 10 和 20
  • 您的原始答案似乎符合我的要求?
  • 我的原始答案只会将10-rate 项目中的一个 设置为0,(因为numberOfItems = 1)你说你希望两者都设置为0.
【解决方案2】:

你可以使用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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    相关资源
    最近更新 更多