Linq按状态分段数据



嘿,我正试图找出在列表中抓取数据段的最优方法。根据他们的类型假设我在一个列表中有以下数据:

public enum StepStatus {
Skipped,
NotStarted,
Completed,
}
public enum StepType 
public class Steps {
StepStatus Status { get; set; }
StepType Type { get; set;}
// Other info
} 

我有一个所有步骤及其状态的列表

//Data
1, StepStatus.Skipped, StepType.Notification
2, StepStatus.Completed, StepType.Notification
3, StepStatus.NotStarted, StepType.Notification
4, StepStatus.NotStarted, StepType.Notification
5, StepStatus.NotStarted, StepType.Approval}
6, StepStatus.NotStarted, StepType.Notification

我想抓取所有未启动的通知,直到并包括第一次批准。所以我想返回列表的这段

3, StepStatus.NotStarted, StepType.Notification
4, StepStatus.NotStarted, StepType.Notification
5, StepStatus.NotStarted, StepType.Approval

我能想到的最简单的方法是。

var firstApprovalStep =  steps.FirstOrDefault(x => x.Status == StepStatus.NotStarted && x.Type == StepType.Approval);
if(null == firstApprovalStep)
{
//If there are no pending approvals left return the pending notfications
return steps.Reverse().TakeWhile(x => x.Status == StepStatus.NotStarted && x.Type == StepType.Notification);
}
//Find the element in the list with that index and grab all prior.
steps.GetNotStartedNotificationsPrior(firstStep);

我想知道是否有一种更简单/更聪明的方法来使用linq抓取这个段?

既然我们知道你使用的是List<T>,我们可以稍微作弊,使用源IEnumerable两次而不会受到太大的惩罚。

这是一个扩展方法:

public static IEnumerable<T> TakePast<T>(this IEnumerable<T> items, Func<T, bool> posFn) => items.Take(items.TakeWhile(i => !posFn(i)).Count()+1);

你可以这样做:

return steps.Where(s => s.StepStatus == StepStatus.NotStarted)
.TakePast(s => s.StepType == StepType.Approval);
当然,这意味着你可以展开扩展方法:
return steps.Where(s => s.StepStatus == StepStatus.NotStarted)
.Take(steps.Where(s => s.StepStatus == StepStatus.NotStarted).TakeWhile(s => s.StepType != StepType.Approval)).Count()+1);

我假设唯一的StepTypes是NotificationApproval,因为您没有定义enum

下面是枚举任何序列一次的泛型实现:

public static IEnumerable<T> TakePast<T>(this IEnumerable<T> items, Func<T, bool> posFn) {
var ie = items.GetEnumerator();
while (ie.MoveNext()) {
yield return ie.Current;
if (posFn(ie.Current))
yield break;
}
}

最新更新