代码之家  ›  专栏  ›  技术社区  ›  hmahdavi

如何按字段分组列表,并通过linq将另一个字段的min分组?

  •  0
  • hmahdavi  · 技术社区  · 8 年前

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

    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 回复  |  直到 8 年前
        1
  •  1
  •   Ivan Stoev    8 年前

    的结果 group by 操作是分组列表,其中分组由一个键和共享该键的元素列表组成。

    让我们来看看您的第一个查询。按操作分组 aFlightList 按日期,因此无需按日期对组元素进行进一步排序(相同)。但你可以按价格订购,所以 First 将以最低价格返回元素。最后,由于 分组依据 结果组可能不是您想要的,您可以订购 分组 通过键(或其部分)。

    综上所述,修改后的查询可能如下:

    (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();
    
        2
  •  1
  •   Jeroen Heier    8 年前

    您可以创建具有所需结果的新对象,并对其执行选择。例子:

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