简体   繁体   English

如何对列表排序 <t> C#中具有一定条件的对象按属性划分

[英]How to sort a list<t> of objects by property with a certain condition in c#

I have this class and in our app and it is used by the driver . 我在我们的应用程序中有这个类,由驱动程序使用。 When the driver opens the app , it is supposed to show current day schedule with clients pickup time and their destinations. 当驾驶员打开应用程序时,它将显示当前的日程安排以及客户的接送时间和目的地。

public class PickUps
{
  public DateTime PickUpTime { get; set; }
  public int PassengerId { get; set; }
  public String PassengerName { get; set; }
  public GeoCoordinate PassengerLocation { get; set; }
}

List<PickUps> objListPickUps = new List<PickUps>();
objListPickUps  = TravelAPI.GetPickupList(int PassenegerId); // fill list of PickUps

Now i want to filter this list by the closest PickUpTime (lets say he opens the app at 11AM and there are pickups scheduled at 10.30AM and 12 Noon it should return the 10.30AM pickup object details. And if the app is opened at 11 AM and pickup was at 10AM and next pickup was at 12Noon then it should return the 10AM object ie when the difference between "current and prev" and "current and next pickup" is same) 现在,我想按最接近的PickUpTime筛选此列表(假设他在上午11点打开应用,并且安排了上午10.30和中午12点的取件,它应该返回10.30 AM取件对象的详细信息。如果应用在上午11点打开并在10AM取货,在12Noon进行下一次取货,则它应返回10AM对象,即“当前和上一个”与“当前和下一次取货”之间的差相同时

I tried below but it doesn't give me the above result i am expecting. 我在下面尝试过,但并没有得到我期望的上述结果。 Any other condition i need to add ? 我需要添加其他条件吗?

var res = objListPickUps.OrderBy( x => (x.PickupTime - DateTimew.Now).Duration).FirstOrDefault();

Duration()是一种方法,而不是属性或字段:

var closestPickup = objListPickUps.OrderBy(x => (x.PickUpTime - DateTime.Now).Duration()).FirstOrDefault(); 

Ok, assuming then what do you want is what did you try (finding a single closest pickup), but did not get a correct result. 好的,假设您想要的是您尝试了什么(找到最接近的一个皮卡),但是没有得到正确的结果。

First, you should capture DateTime.Now in a variable so it doesn't change during the query. 首先,您应该在变量中捕获DateTime.Now ,以便它在查询期间不会更改。

Now on the subject. 现在就这个话题。

One thing you can do is to add ThenBy(x => x.PickupTime) to your query, which will handle the case with equal differences: 您可以做的一件事是向查询中添加ThenBy(x => x.PickupTime) ,这将以相等的差异处理这种情况:

var baseTime = DateTime.Now;
var closestPickUp = objListPickUps
    .OrderBy(x => (x.PickupTime - baseTime).Duration())
    .ThenBy(x => x.PickupTime)
    .FirstOrDefault();

But I would suggest you to not use the above LINQ method, because it's inefficient. 但我建议您不要使用上面的LINQ方法,因为它效率低下。 There is no need to sort the list ( O(N*log(N) time) in order to find what you need. Instead, you can use a simple loop ( O(N) ) as follows. Let also encapsulate it inside a method: 无需对列表进行排序( O(N * log(N)时间)即可找到所需的内容,而是可以按如下所示使用简单的循环( O(N) )。也可以将其封装在方法:

static PickUps FindClosestPickUp(List<PickUps> pickUpList, DateTime baseTime)
{
    PickUps closestPickUp = null;
    TimeSpan closestDuration = default(TimeSpan);
    foreach (var pickUp in pickUpList)
    {
        var duration = (pickUp.PickUpTime - baseTime).Duration();
        if (closestPickUp == null || closestDuration > duration || (closestDuration == duration && closestPickUp.PickUpTime > pickUp.PickUpTime))
        {
            closestPickUp = pickUp;
            closestDuration = duration;
        }
    }
    return closestPickUp;
}

and the usage will be simple 而且用法很简单

var closestPickUp = FindClosestPickUp(objListPickUps, DateTime.Now);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM