0

I am trying to make a variable in my model that retrieves all available skills to later display them in a DDL. I have one variable that contains all of the skills and one variable that displays all of the skills an employee has already rated. I want to check all of the skills against the rated skills so that only the unrated skills are added to the new variable in the model. The only way I could think of to do this is to use a foreach loop to check for the values in the AllSkills variable.

model:

public IEnumerable<long> AvailableSkills { get; set; }
public IEnumerable<long> AllSkills { get; set; }
public IEnumerable <long> EmployeeRatings { get; set; }          
public IEnumerable<Rating> Ratings { get; set; }
public IEnumerable<Skill> Skills { get; set; }
public long SkillId { get; set; }

Controller:

model.AllSkills = db.Skills.OrderBy(s => s.SkillName).Select(s => s.SkillId);
model.EmployeeRatings = db.Ratings.Where(r => r.EmployeeId == User.Identity.Name.Remove(0, 8)).OrderBy(s => s.SkillId).Distinct();

foreach (var skill in model.EmployeeRatings)
        {
            model.AvailableSkills = model.AllSkills.Where(s => s != skill);
        }

I want to do something like the following code in the foreach loop:

model.AvailableSkills += model.AllSkills.Where(s=> s != skill); but this is not allowed.

The problem is that this for each loop above is assigning the model.AvailableSkills to the every skill but the last one that is in the foreach loop (as it should). How do I make it so that every one of the duplicate skills are excluded from model.AvailableSkills?

3
  • I nowhere see the user in your filter so where and how are you doing this.i don't understand the question otherwise. Commented Aug 3, 2015 at 20:42
  • @Ric.Net Sorry I had an error in my question. I have updated it. Commented Aug 3, 2015 at 20:46
  • @brroshan I have updated it, does that help? Commented Aug 3, 2015 at 20:58

4 Answers 4

1

Using LINQ is IMO more readable if you use to query syntax opposed to the method chaining syntax.

model.AllSkills = 
   from skill in db.Skills
   orderby skill.SkillName
   select skill.SkillId;

model.EmployeeRatings = 
     from rating in db.Ratings
     let employeeId = User.Identity.Name.Remove(0, 8)
     where rating.EmployeeId == employeeId
     orderby rating.SkillId
     select rating.SkillId

You can use the Except() extension method to remove items from the collection.

// exclude the 'owned' skils
model.AvailableSkills = model.AllSkills.Except(model.EmployeeRatings);

And you probably want to distinct the results:

model.AvailableSkills = model.AvailableSkills.Distinct(); 

Last but not least: Because you select the SkillId I'm unsure why you would order the results. This does not make sense especially because you order by different properties in both lists. Furtermore you probably want to select more details to display to the user, but to know this we need more details on your model.

Sign up to request clarification or add additional context in comments.

Comments

0

Assuming EmployeeRatings contains rated skills, and you want AvailableSkills to have only skills not in EmployeeRatings but are in AllSkills, I think this is what you like to do:

model.AvailableSkills = model.AllSkills
     .Where(s => !model.EmployeeRatings.Contains(s));

Comments

0

Consider two classes like this:

public class Skill
{
    public int Id { get; set; }
}

public class Employee
{
    public int[] RatedSkills { get; set; }
}

var skills = new List<Skill>
        {
            new Skill{ Id = 1}, new Skill{Id = 2}, new Skill{ Id = 3}, new Skill { Id = 4}
        };

        var emp = new Employee
        {
            RatedSkills = new int[] { 1,2 }
        };

        var availableSkills = skills.Select(s => s.Id).Except(emp.RatedSkills);

        Console.Read();

The rating has an Id property an an employee has an int[] to hold his/her selected ratings. From there it's easy to filter

Comments

0

Following your current approach, you can use AddRange with a list. Something like:

List<long> availableSkills = new List<long>();

foreach (var skill in model.EmployeeRatings)
{
    availableSkills.AddRange(model.AllSkills.Where(s => s != skill));
}

model.AvailableSkills = availableSkills;

Or you can achieve this with a more compact approach, and I believe Except removes dupes:

model.AvailableSkills = model.AllSkills.Except(model.EmployeeRatings);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.