Linq - 根据“重量”和“订单”从列表中获取项目

时间:2015-04-20 06:34:49

标签: c# linq linq-to-sql lambda

我正在尝试创建一个计算用户个人资料完整性的类,我正在尝试接下来的步骤(Evaluators)以便用户实现下一个完整性级别。

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")

2 个答案:

答案 0 :(得分:3)

你可以这样做:

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循环......

也可以轻松实现

答案 1 :(得分:0)

以下行不起作用

.Select(evaluator => evaluator.Run(status))
​

您按照他们进入List&lt;&gt;的顺序一次一个地通过评估者进行枚举。您的函数需要所有评估者,您需要传递整个列表'Evaluators'。