如何找到2个列表的相交 [英] How to Find Intersect of 2 Lists
问题描述
亲爱的所有人,
你可以帮我解决下面的问题。
我有一个包含熟练用户的列表,列表<技能>(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 onlinq 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屋!