Click here to Skip to main content
15,891,828 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Dear All,
Can you please help me on bellow issue.
i have a List contain Skilled Users, List<skills>(UserID,SkillID) & i have another List of Users List<users>(UserID,UserName)

Ex. Skill1 User1
Skill1 User2
Skill2 User1
Skill2 User4

Now , if i choose skill1 & skill2 it should return distinct User (1,2,4) along with Name have both skills.
Posted

How about Google?
E.g. the first hit on linq list join c# is http://stackoverflow.com/questions/2723985/linq-join-2-listts[^]...

[EDIT]
As response to the comments below, I guess grouping is the "missing link" to the OP's question. E.g.
C#
var query = from su in skilledUserRelation
            where su.SkillId == ...
            group su.SkillId by su.UserId into userWithGroupedSkills
            select new {
                         User   = userWithGroupedSkills.Key,
                         Skills = userWithGroupedSkills.ToList()
                       };
foreach (var item in query)
{
    Console.WriteLine("User = {0}: {1}", item.User, string.Join(",", item.Skills));
}

[/EDIT]

Cheers
Andi
 
Share this answer
 
v2
Comments
BillWoodruff 18-Dec-15 3:11am    
I'd like to see an example of code using 'join that would handle the type of query the OP wants here.
Andreas Gieriet 18-Dec-15 4:52am    
See edited solution.
Cheers
Andi
Your title implies a different question that the content. By all means accept Solution 1 but I'll post this in case anyone is trying to find the Intersect answer.

There is a Linq Intersect extension:

C#
int[] a = new [] {1,2,3,4,5,6};
int[] b = new [] {3,4,6,7,8,9};

int[] c = a.Intersect(b);

Console.WriteLine("output:");
foreach(int i in c){
  Console.WriteLine(i);
}

//  output:
//  3
//  4
//  6


To answer your specific issue (using a join as mentioned in Solution 1), here is an example:

C#
class SkilledUser{
  public string Skill {get;set;}
  public int UserId {get;set}
}
class User{
  public string UserName {get;set;}
  public int UserId {get;set}
}
var _users = GetUserList();
var _skilledUsers = new List<SkilledUser>{
  new SkilledUser{Skill = "Skill1", UserId=1},
  new SkilledUser{Skill = "Skill1", UserId=2},
  new SkilledUser{Skill = "Skill2", UserId=1},
  new SkilledUser{Skill = "Skill2", UserId=4},
}
public List<SkilledUser> GetUserOfAnySkill(params string[] Skills){

  return Skills
      .Join(
          _skilledUsers, //IEnumerable to join
          s=>s.Skill,    //left part comparison (from Skills Array)
          su=>su.Skill,  //right part comparison (from _skilledUsers List)
          (s,su)=>su)    //result select.  
//You can keep both items linked with the select: (s,su)=>new{s,su} which will result in an anonymous class, but we don't need the Skills array for the next part
      .Join(
         _users,
         su=>su.UserId,
         u=>u.UserId,
         (su,u)=>u)
//as above we use result of the first join to select the desired users.
//There may well be duplicates still, but Linq can solve that too
      .Distict() //get rid of duplicates      
      .ToList()  //The previous steps set up the query, ToList() is one way to execute it
}


I hope that helps. Let me know if you need anything more ^_^

Andy
 
Share this answer
 
v2
Comments
BillWoodruff 18-Dec-15 3:10am    
Using Intersect would never work in this case without defining a custom IEqualityComparer<t>; that would not be a technique of choice in this case where the OP clearly wants the results of a query.

If you can show a valid solution to the OP's question using only Intersect and a custom IEqualityComparer<t>, you get my #5.
Andy Lanng 18-Dec-15 4:02am    
As I stated at the start: I wasn't answering the guts of the question, just the title "How to Find Intersect of 2 Lists". I only did it because I usually search for questions but find irrelevant answers to completely different questions.

The solution to the OPs question would indeed be a Join as in Solution 1 so I'll update by solution to include that example
I find this an interesting question because while you can use Linq (as shown at the end, here) to create queries from the Classes the OP describes, I think the Linq required is complex, far too complex. There's an easier, and, imho, better way: change the Classes' structure.

By adding a List of SkillID's to the basic 'User Class, you will make queries so much simpler. Here's an example:
C#
public class User
{
    public int ID { set; get; }
    public string UserName { set; get; }
    public List<int> UserSkills { set; get; }

    public User(int id, string name, params int[] skills)
    {
        ID = id;
        UserName = name;
        UserSkills = new List<int>(skills);
    }

    public void AddSkill(int skillid)
    {
        if (!UserSkills.Contains(skillid)) UserSkills.Add(skillid);
    }
}</int></int>
Then, it becomes very easy to query on different attributes:
C#
// assume there's a List of User named 'uList:
List<user> usersWithSkillsOneAndTwo = uList.Where(usr => usr.UserSkills.Contains(1) && usr.UserSkills.Contains(2)).ToList();</user>
Compare the above with this example of using Linq with the Class structures the OP is (maybe) using now:
C#
<pre lang="C#">public class Users
{
    public int ID { set; get; }
}

public class User : Users
{
    public string UserName { set; get; }

    public User(int id, string name)
    {
        ID = id;
        UserName = name;
    }
}

public class SkilledUser : Users
{
    public int SkillID { set; get; }

    public SkilledUser(int id, int skillid)
    {
        ID = id;
        SkillID = skillid;
    }
}
Assuming: a List<User> 'uList; and, a List<SkilledUser 'suList: you could construct a Dictionary<int, List<int>> to map Users to SkilledUsers:
C#
// var isect = uList.Intersect()
Dictionary<int, List<int>> SkillsByUsers = uList.ToDictionary
(
    // key is the ID of the User
    uitm => uitm.ID,
    // Value is a List of the SkilledUsers selected by User.ID
    uitm => suList
        .Where(suitm => suitm.ID == uitm.ID)
            .Select(suid => suid.SkillID)
                .ToList()
);

List<User> UsersWithSkillsOneAndTwo = SkillsByUsers
    .Where
        // get KeyValuePairs where Value contains 1,2
        (suitm => suitm.Value.Contains(1) && suitm.Value.Contains(2))
            // project Anonymous Type selected from the List of Users based on SkillID
            .Select(kvpitm => new
                { itm = uList.First(uitm => uitm.ID == kvpitm.Key)})
                // get the User out of the Anonymous Type
                .Select(aitm => aitm.itm)
                    .ToList();
Perhaps someone will come along here and replace this Linq with a blindingly simple version :)
 
Share this answer
 
Comments
Andreas Gieriet 18-Dec-15 4:45am    
The OP is not too clear, i.e. we must invent the data an guess what exactly is the content of the lists (tables?). Bit I think the query the OP wants is "grouping", e.g. var query = from su in skilledUserRelation group su.SkillId by su.UserId into userWithGroupedSkills select new { User = userWithGroupedSkills.Key, Skills = userWithGroupedSkills.ToList() };. He might add filtering before grouping.
Cheers
Andi

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900