Skip to main content
 首页 » 编程设计

c#之Linq之从基于 "weight"和 "order"的列表中获取项目

2024年06月20日27bhlsheji

我正在尝试创建一个类来计算用户配置文件的完整性,并且我正在尝试获取后续步骤(评估程序)以便用户实现下一个完整性级别。

public class Evaluator 
{ 
    public Evaluator(string name, int value, Func<CompletionStatus, bool> rule) 
    { 
        Name = name; 
        Value = value; 
        Action = rule; 
    } 
 
    public int Value { get; private set; } 
    public Func<Completion, bool> Rule { get; private set; } 
    public bool IsCompleted { get;set; } 
 
    public int Run(CompletionStatus status) 
    { 
         IsCompleted = Rule(status); 
         return IsCompleted ? Value : 0;         
    } 
} 
 
class CompletionManager 
{ 
     public List<Evaluator> Evaluators { get;set; } 
 
     public CompletionManager() { 
 
        Evaluators = new List<Evaluator>() { 
        new Evaluator("Email", 10, status => !String.IsNullOrWhiteSpace(status.Email)), 
        new Evaluator("DOB", 10, status => status.DateOfBirth.HasValue), 
        new Evaluator("Mobile", 20, status => !String.IsNullOrWhiteSpace(status.Mobile)), 
        new Evaluator("Address", 20, status => !String.IsNullOrWhiteSpace( status.Address)), 
        new Evaluator("Profession", 40, status => status.HasProfession), 
 
    }; 
} 

用法

  Main() { 
 
   var status = new CompletionStatus 
            { 
                Email = "dummy@gmail.com", 
                DateOfBirth = null, 
                Mobile = "", 
                Address = "", 
                HasProfession = false, 
            }; 
 
    CompletionManager cm = new CompletionManager(); 
 
     var profileCompletion = (byte) cm.Evaluators 
            .Select(evaluator => evaluator.Run(status)) 
            .Sum(); 
 
     profileCompletion.Dump(); // result= 10% complete 
 
     var nextEvaluators = cm.EvaluatorsToTheNextLevel(profileCompletion); // get the next 40% 
 
 } 

问题:在此示例中 - 如何获取与用户必须完成的下一个 40% 相对应的 Evaluator 列表,以便配置文件完成度为 >= 50% ;

在上面的示例中,我想获取 Evaluator("DOB")Evaluator("Mobile")Evaluator("Address")

class CompletionManager { 
.... 
 public List<Evaluator> EvaluatorsToTheNextLevel(int completionStatus) { 
 
    // assuming completionStatus = 10%, then we have to get the next 40% worth of evaluators 
       var percentBeforeNxtLevel = 50 - completionStatus; 
       return Evaluators.Where(e => e.IsCompleted == false && ???); 
   } 
} 

注意:还考虑了评估者的顺序,因此如果我们要获得下一个 40%,我们不需要 Evaluator("Profession"),因为它位于堆栈的底部

还有:这应该是灵活的;如果我这样做

var status = new CompletionStatus 
            { 
                Email = "", 
                DateOfBirth = null, 
                Mobile = "091920", 
                Address = "", 
                HasProfession = false, 
            }; 

然后我们应该得到 Evaluator("Email"), Evaluator("DOB"), Evaluator("Address")

请您参考如下方法:

你可以这样做:

public List<Evaluator> EvaluatorsToTheNextLevel(int completionStatus) { 
 
    // assuming completionStatus = 10%, then we have to get the next 40% worth of evaluators 
       var percentBeforeNxtLevel = 50 - completionStatus; 
       var tmp = 0; 
       return Evaluators 
          .Where(e => e.IsCompleted == false) 
          .TakeWhile(x => { 
              tmp +=x.Value; 
              return tmp <= percentBeforeNxtLevel; 
            }) 
           .ToList(); 
   } 

当然,这也可以通过简单的 while 循环轻松实现...