从枚举中选择最不常见的项目

时间:2015-03-03 09:38:14

标签: c# linq

一些背景信息:我目前正在建立一个人们可以预订餐厅的网站。在预订时,人们可以选择一个小时,他们想来吃饭。他们没有选择特定时间,但他们从下拉菜单中选择“一般”时间戳(例如11h - 12h,13h - 14h,17h - 18h等)。

提交预订时,系统需要为客户提供更具体的时间。这样做是为了向客户传播一点,这样我们就可以避免客户出现大幅增长。 “更具体的时间”是小时加0,15,30或45分钟(我用Minutes-enumeration做了这个。)

我创建了一个“TimeStamp”类,其中包含一个小时和分钟枚举。 “预订”类包含有关预订的一些信息和时间戳。

现在,在进行新预订时,我需要找到最佳的“分钟”值。这是保留金额最少的值(在选定的小时内)。

这是我到目前为止编写的代码,但它不起作用:

var reservationsInTheSameHour = context.Reservations
                                    .Where(r => r.TimeStamp.Hour == model.Uur);
var bestMinuteChoice = reservationsInTheSameHour
                           .GroupBy(r => r.TimeStamp.Minute)
                           .OrderByDescending(m => m.Count())
                           .Select(rr => rr.Key);

我认为这不起作用的原因是因为还没有选择几分钟,所以不会选择它们。

有没有人想到更有效的方法,或者可以帮助我解决这个问题?

编辑:

这是小时和分钟 - 枚举:

    public enum Minutes
    {
        _00,
        _15,
        _30,
        _45
    }

    public enum Hours
    {
        [Display(Name = "Tussen 11u en 12u")]
        _11u,

        [Display(Name = "Tussen 12u en 13u")]
        _12u,

        [Display(Name = "Tussen 13u en 14u")]
        _13u,

        [Display(Name = "Tussen 17u en 18u")]
        _17u,

        [Display(Name = "Tussen 18u en 19u")]
        _18u,

        [Display(Name = "Tussen 19u en 20u")]
        _19u,

        [Display(Name = "Tussen 20u en 21u")]
        _20u,

        [Display(Name = "Tussen 21u en 22u")]
        _21u
    }

我设法通过使用包含枚举值的字典以及预订中存在的分钟值的次数来自行解决问题。

var reservationsInTheSameHour = context.Reservations.Where(r => r.TimeStamp.Hour == model.Uur);
var minuteCounts = Enum.GetValues(typeof (TimeStamp.Minutes))
                       .Cast<TimeStamp.Minutes>()
                        .ToDictionary(
                                minute => minute,
                                minute => reservationsInTheSameHour.Count(r => r.TimeStamp.Minute == minute)
                         );
var bestMinute = minuteCounts.FirstOrDefault(a => a.Value == minuteCounts.Min(aa => aa.Value)).Key;
reservation.TimeStamp = new TimeStamp(model.Uur, bestMinute);

aush的解决方案更加优雅。这就是我最终的结果:

private static TimeStamp.Minutes GetOptimalMinute(IQueryable<Reservation> reservations, TimeStamp.Hours hour)
{
    foreach (TimeStamp.Minutes enumVal in Enum.GetValues(typeof (TimeStamp.Minutes))
        .Cast<TimeStamp.Minutes>()
        .Where(enumVal => reservations.All(r => r.TimeStamp.Minute != enumVal)))
    {
        return enumVal;
    }


    return reservations.Where(r => r.TimeStamp.Hour == hour)
        .GroupBy(r => r.TimeStamp.Minute)
        .OrderBy(m => m.Count())
        .Select(rr => rr.Key).First();
}

1 个答案:

答案 0 :(得分:1)

你是对的,你的问题是你正在寻找最不常见的。因此,您可以先检查是否有不存在的枚举值:

foreach (var enumVal in Enum.GetValues(Minute))
{
    if (reservations.All(r => r.Minute != enumVal))
    {
        return enumVal;
    }
}

return reservations.Where(r => r.Hour == Hour.eleven)
                   .GroupBy(r => r.Minute)
                   .OrderBy(m => m.Count())
                   .Select(rr => rr.Key)
                   .Last();