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

标签 c# linq linq-to-sql lambda

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

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 循环轻松实现...

关于c# - Linq - 从基于 "weight"和 "order"的列表中获取项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29740750/

相关文章:

c# - 使用 linq to SQL 保存 unicode 字符

c# - NHibernate Linq Select Projection - 使用部分选择检索完整实体

c# - 如何删除 MVC/Entity Framework 中的对象 : The object cannot be deleted because it was not found in the ObjectStateManager

c# - 使用没有 id 的列表 <strings> 加入 Linq 以从中索引

c# - CS0436 共享项目的编译器警告

c# - 如何以编程方式在 .NET Web 服务的 IIS 中设置集成 Windows 身份验证?

c# - 添加后 FirstOrDefault 似乎没有调用数据库

c# - Prism 5 Wpf - 登录窗口显示两次

c# - Linq-to-sql 代码不返回结果,即使生成的 sql 返回结果

c# - Linq-to-Sql:递归获取 child