我正在尝试搜索按插槽号搜索多个客户的空时段。如果该客户有时间,则应返回找到的第一个客户。
示例数据(每个客户都有一个唯一的插槽号)
customer 1: slotnumber 0, time 0
customer 1: slotnumber 0, time 1
customer 1: slotnumber 0, time 2
customer 1: slotnumber 0, time 4
customer 2: slotnumber 1, time 0
customer 2: slotnumber 1, time 1
我有以下课程:
public class CustomerSlot
{
public int customerid { get; set; }
public int slotnumber { get; set; }
public int time { get; set; }
}
然后我有一个customersslots列表:
List<CustomerSlot> lstCustomerSlots = new List<CustomerSlot>();
现在假设我想使用上述数据找到时间3可用的第一个插槽。
这是我需要帮助的地方。我没有正确的语法来由客户分组并返回具有该时间段的客户:
CustomerSlot timeSpaceFound = lstCustomerSlots
.Where(t => t.time != 3) // Search for time 3
.GroupBy(c => c.customerid) // Search an entire customer
.OrderBy(c => c.customerid) // Start searching by the order of first customerid
.FirstOrDefault();
任何帮助设置上述lambda将不胜感激。没有找到任何在线搜索解决方案的示例。谢谢。
答案 0 :(得分:1)
您需要按客户对时间进行分组,然后找到没有时间段的最低客户ID:
var timeSpaceFound = lstCustomerSlots.GroupBy(c => c.customerid)
.Where(cg => !cg.Any(c => c.time == 3))
.OrderBy(cg => cg.Key)
.FirstOrDefault()
?.Key;
我更喜欢使用扩展方法MinBy
:
public static T MinBy<T, TKey>(this IEnumerable<T> src, Func<T,TKey> keySelector, Comparer<TKey> keyComparer) => src.Aggregate((a, b) => keyComparer.Compare(keySelector(a), keySelector(b)) < 0 ? a : b);
public static T MinBy<T, TKey>(this IEnumerable<T> src, Func<T,TKey> keySelector) => src.Aggregate((a, b) => Comparer<TKey>.Default.Compare(keySelector(a), keySelector(b)) < 0 ? a : b);
然后你就做了
var timeSpaceFound = lstCustomerSlots.GroupBy(c => c.customerid)
.Where(cg => !cg.Any(c => c.time == 4))
.MinBy(cg => cg.Key)
?.Key;
这应该更有效率,因为Aggregate
只能通过列表一次。
如果您希望收到CustomerSlot
而不是customerid
,则需要获得该组中的第一个(除非您需要特定的时间段):
var timeSpaceFound = lstCustomerSlots.GroupBy(c => c.customerid)
.Where(cg => !cg.Any(c => c.time == 4))
.MinBy(cg => cg.Key)
.FirstOrDefault();
答案 1 :(得分:1)
如果我理解正确,您希望从列表中选择3
已经没有任何时段条目的第一个客户。
CustomerSlot timeSpaceFound = lstCustomerSlots
.GroupBy(c => c.customerid) // Group entries by customer
.Where(g => g.All(c => c.time != 3)) // Remove all groups that have a time entry of 3
.OrderBy(g => g.Key) // Start searching by the order of first customerid
.FirstOrDefault() // Select the first group
?.FirstOrDefault(); // Select the first CustomerSlot entry in the group.