c# - Linq OrderBy 子列表

标签 c# linq sorting

我正在尝试执行一个相当简单的命令,但似乎正在为如何去做而苦苦挣扎。以我有这两个类为例。

public class Method
{
    public int Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public List<Slot> Slots { get; set; }
}

public class Slot
{
    public DateTime ExpectedDeliveryDate { get; set; }
}

使用下面的代码,我想按最便宜的选项订购,然后按最快的交货日期订购。

var methods = new List<Method>();

methods.Add(new Method { Id = 1, Name = "Standard", Price = 0M, Slots = new List<Slot> { new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(5).Date } } });
methods.Add(new Method { Id = 2, Name = "Super Fast Next Day", Price = 0M, Slots = new List<Slot> { new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(1).Date } } });

var b = methods.OrderBy(x => x.Price)
    .ThenBy(y => y.Slots.OrderBy(t => t.ExpectedDeliveryDate.Date)
        .ThenBy(t => t.ExpectedDeliveryDate.TimeOfDay))
            .ToList();

我在这里遇到的麻烦是我收到一个运行时错误,指出“至少一个对象必须实现 IComparable”。

虽然我可以通过实现 IComparable 接口(interface)来解决这个问题,但我想知道是否可以这样做。我想好像我有这段代码(见下文)它工作正常。

var slots = new List<Slot>();

slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(5).Date });
slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(1).Date });
slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(3).Date });
slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.Date });

var d = slots.OrderBy(x => x.ExpectedDeliveryDate);

干杯,DS。

对于上面示例中的 xyz 等变量命名表示歉意:) 可以复制和粘贴代码以获得操作乐趣。

编辑 - 更新以简化代码示例。 - 预期结果将在成功排序之后

Input
  ID     Name            Price    Slot
  1      Standard        0        DateTime.Now.AddDays(5).Date
  2      Super Fast      0        DateTime.Now.Date

Output
  2      Super Fast      0        DateTime.Now.Date  
  1      Standard        0        DateTime.Now.AddDays(5).Date

所以我的超快速选项应该是最重要的,因为它是最便宜的,当然还有最快的交货日期。

最佳答案

您可以使用 Enumerable.Min()选择日期最早的时段,如下所示:

        var query = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate).Year)
            .ThenBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate).Month)
            .ThenBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate).Date)
            .ToList();

或者,只是

        var query = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate.Date))
            .ToList();

请注意,当输入序列为空且被最小化的类型为值类型时,Min() 将抛出异常。如果你想避免异常,你可以这样做:

        var query2 = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => (DateTime?)(s.ExpectedDeliveryDate.Date)))
            .ToList();

通过将 DateTime 转换为可空值,Min() 将为空序列和具有空槽的 Method 对象返回 null列表将排序到开头。

关于c# - Linq OrderBy 子列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27686594/

相关文章:

c# - C# :Cross-thread operation not valid: Control 'lblp4' accessed from a Cross-thread operation not valid 中的线程异常错误

c# - 使用 linq/Entity Framework 查询多对多关系。代码优先

c# - LINQ to Entities 无法识别方法 'System.Object GetValue(...)'

c# - 在 LINQ 选择期间无法设置枚举属性

java - 如何构造此快速排序以在特定索引值处停止快速排序并开始选择排序?

c# - BitmapData.Stride 与 GetPixelFormatSize(BitmapData.PixelFormat) 除以 8

c# - 使用 C# 变量作为表元素

javascript - 使用 json 内容对网格进行排序

c# - MVC List<SelectListItem> 带有为每个项目创建 optgroup 的组

c# - C# 中具有两种不同数据类型的二维数组