如何按字段对列表进行分组,并通过linq选择另一个字段的组min?

时间:2016-07-24 06:55:41

标签: c# linq

我有一个航班列表,我尝试将其与日期字段分组,然后选择最低价格到每组。结果我应该得到 每天最便宜的航班。

enter image description here

(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();

这样就会出错。

怎么做?

2 个答案:

答案 0 :(得分:1)

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();

答案 1 :(得分:1)

您可以使用所需的结果创建新对象,并对其执行选择。例如:

    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);
    }