Linq - Get items from the list based on "weight" and "order"

I am trying to create a class which compute the completeness of a profile of a user and I am trying to get the next steps (Evaluators) in order for the user to achieve the next completeness level.

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), }; }

Usage

Main() { var status = new CompletionStatus { Email = "[email protected]", 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% }

Problem: In this example - how do I get the list of Evaluator that correspond to the next 40% that the user have to complete so that the profile completion is >= 50%;

In the example above, I want to get the Evaluator("DOB"), Evaluator("Mobile") and 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 && ???); } }

Note: order of Evaluators is also considered so if we are getting the next 40%, we dont want the Evaluator("Profession") as it is in the bottom of the stack

And Also: THIS should be flexible; if I do

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

then we should get Evaluator("Email"), Evaluator("DOB"), Evaluator("Address")

-------------Problems Reply------------

You could do something like that :

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();
}

Of course, this could be also easily achieved with a simple while loop...

The line below will not work

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

You are enumerating through the evaluators one at a time in the order that they go into the List<>. Your function needs all the evaluators to you need to pass the entire list 'Evaluators'.

Category:c# Views:2 Time:2018-02-15

Related post

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.117 (s). 11 q(s)