如何找到2个列表的相交 [英] How to Find Intersect of 2 Lists

查看:69
本文介绍了如何找到2个列表的相交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的所有人,

你可以帮我解决下面的问题。

我有一个包含熟练用户的列表,列表<技能>(UserID,SkillID)&我有另一个用户列表列表< users>(UserID,UserName)



Ex。技能1用户1

技能1用户2

技能2用户1

技能2用户4



现在,如果我选择skill1& skill2它应该返回不同的用户(1,2,4)和Name都有这两种技能。

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.

推荐答案

谷歌怎么样?

例如第一次点击 linq list join c# http: //stackoverflow.com/questions/2723985/linq-join-2-listts [ ^ ] ...





作为回复评论下面,我猜分组是OP问题的缺失链接。例如。
How about Google?
E.g. the first hit on linq list join c# is http://stackoverflow.com/questions/2723985/linq-join-2-listts[^]...


As response to the comments below, I guess grouping is the "missing link" to the OP's question. E.g.
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]



干杯

Andi


[/EDIT]

Cheers
Andi


您的标题暗示了内容的另一个问题。一定要接受解决方案1但我会发布这个以防任何人试图找到相交答案。



有一个Linq Intersect扩展名:



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:

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





要回答您的具体问题(使用解决方案1中提到的联接),这里有一个例子:





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

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
}





我希望有所帮助。如果您需要更多信息,请告诉我^ _ ^



Andy



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

Andy


我发现这是一个有趣的问题因为你可以使用Linq(如最后所示,这里)从OP描述的类中创建查询,我认为Linq所需要的是复杂的,太复杂了。有一种更简单,更好的方式:更改Classes的结构。



通过向基本的'用户类添加SkillID列表,您将进行查询这么简单。以下是一个示例:
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:
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:

// 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>

将上面这个使用Linq的例子与OP的类结构进行比较(也许)现在使用:

Compare the above with this example of using Linq with the Class structures the OP is (maybe) using now:

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

假设:列表<用户> uList;并且,List< SkilledUser'suList:你可以构造一个Dictionary< int,List< int>>将用户映射到SkilledUsers:

Assuming: a List<User> 'uList; and, a List<SkilledUser 'suList: you could construct a Dictionary<int, List<int>> to map Users to SkilledUsers:

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

也许有人会来这里用一个非常简单的版本替换这个Linq:)

Perhaps someone will come along here and replace this Linq with a blindingly simple version :)


这篇关于如何找到2个列表的相交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆