如何按字段对列表进行分组,并通过linq选择另一个字段的分组min?
问题描述:
我有一个航班的列表,我试图用日期字段对它进行分组,然后选择它进入每个组的最低价格。在结果我应该得到 每天最便宜的航班。如何按字段对列表进行分组,并通过linq选择另一个字段的分组min?
(from flights in aFlightList
where flights.IsDeparture && flights.OnlyTour == "0" && flights.OnlyPhone == "0"
group flights by flights.FlightDateFull
into grouping
select grouping.OrderBy(a => a.FlightDateFull).First()).ToArray();
此代码按日期分组列表,但无法获得特价机票。 我试试这样:
(from flights in aFlightList
where flights.IsDeparture && flights.OnlyTour == "0" && flights.OnlyPhone == "0"
group flights by flights.FlightDateFull
into grouping
select grouping.OrderBy(a => a.FlightDateFull).Min(d=>d.PriceView)).ToArray();
这样就会出错。
如何做到这一点?
答
group by
操作的结果是一个分组列表,其中分组由一个密钥和共享该密钥的元素列表组成。
让我们开始您的第一个查询。按操作分组按日期分组aFlightList
,因此不需要按日期进一步排序组元素(它是一个且相同的)。但您可以按价格订购,因此First
将以最低价格返回元素。最后,由于group by
生成的组的顺序可能不是您想要的,您可以通过密钥(或其一部分)来订购分组。
与所有他这样说,修改后的查询可能是这样的:
(from flights in aFlightList
where flights.IsDeparture && flights.OnlyTour == "0" && flights.OnlyPhone == "0"
group flights by flights.FlightDateFull
into grouping
orderby grouping.Key
select grouping.OrderBy(e => e.PriceView).First())
.ToArray();
答
您可以创建你想要的结果的新对象,并在执行选择。例如:
class Flight
{
public bool IsDeparture;
public string OnlyTour;
public string OnlyPhone;
public DateTime FlightDateFull;
public decimal PriceView;
}
[TestMethod]
public void FlightTest()
{
// Arrange
var flightList = new List<Flight> {
new Flight { IsDeparture = true, OnlyPhone = "0", OnlyTour = "0", FlightDateFull = new DateTime(2016,8,7), PriceView = 1 },
new Flight { IsDeparture = true, OnlyPhone = "0", OnlyTour = "0", FlightDateFull = new DateTime(2016,8,7), PriceView = 2 },
new Flight { IsDeparture = true, OnlyPhone = "0", OnlyTour = "0", FlightDateFull = new DateTime(2016,8,8), PriceView = 2 },
new Flight { IsDeparture = true, OnlyPhone = "0", OnlyTour = "0", FlightDateFull = new DateTime(2016,8,8), PriceView = 3 }
};
// Act
var result = (from flights in flightList
where flights.IsDeparture && flights.OnlyTour == "0" && flights.OnlyPhone == "0"
group flights by flights.FlightDateFull into grouping
select new { Date = grouping.Key, MinPrice = grouping.Min(a => a.PriceView) }).OrderBy(a => a.Date).ToList();
// Assert
Assert.AreEqual(new DateTime(2016, 8, 7), result[0].Date);
Assert.AreEqual(1, result[0].MinPrice);
Assert.AreEqual(new DateTime(2016, 8, 8), result[1].Date);
Assert.AreEqual(2, result[1].MinPrice);
}