从 3 个不同的列表中获取匹配对象的列表
Get list of matching objects from 3 different lists
我正在锻炼一项任务。基本上我在 C# 代码端得到了 3 个不同的列表。 Class 员工包含技能列表。还有员工名单。
例如:
class Employee
{
List<Skills> Skills;
}
class Skills
{
int Id;
int Name;
}
class Where_Im_Working_Currently
{
List<Employee> employees ;
}
我想要实现的是从每个人那里获得共同技能的列表。假设我们有 3 名员工,所有 3 名员工都有 JAVA 共同技能,例如 { id = x , name = JAVA }.
因此3名员工的技能都相似,需要提取id和name。
注意:我正在尝试获得所有匹配技能,而不仅仅是技能的子集
for e.g.
Case 1: Perfect match. (Get List having a, b, c)
list 1 => a, b, c
list 2 => a, b, c
list 3 => a, b, c
Case 1: No match. (Get Null list)
list 1 => a, b, c
list 2 => a, b,
list 3 => b, c
以下是我提出的查询:
var skills= employees.Select(x => x.Skills.Select(p => p.Id== x.Skill[0].Id && p.Name == x.Skill[0].Name));
但这会给 IEnumerable 带来错误,我无法形成 LINQ。
欢迎任何指点或帮助。
这可能不是最优化的方法,但这里有一个解决方案,可以输出所有员工共有的技能。
关键是使用 SelectMany
获取子列表。
public class Employee
{
public List<Skills> Skills { get; set; }
}
public class Skills
{
public int Id { get; set; }
public string Name { get; set; }
}
[Test]
public void GetSomeSkills()
{
var employees = new List<Employee>
{
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 2, Name = "C#" } } },
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 3, Name = "Cooking" } } },
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" } } },
//new Employee { Skills = new List<Skills> { new Skills { Id = 4, Name = "C++" } } }
};
var allSkills = employees.SelectMany(x => x.Skills).ToList();
Console.WriteLine(string.Join(", ", allSkills.Select(x => x.Name)));
// Output: Java, C#, Java, Cooking, Java
var commonSkills = employees.SelectMany(e =>
e.Skills.Where(s => employees.All(e2 => e2.Skills.Select(x => x.Id).Contains(s.Id)))).ToList();
Console.WriteLine(string.Join(", ", commonSkills.Select(x => x.Name)));
// Output: Java, Java, Java
}
如果您取消对最后一位员工的注释,您的结果将为零,因为不再有一项对所有员工都通用的技能。
您可能还想获得不同的结果,但听起来您已经知道该怎么做。
修改原始问题后编辑:
下面只输出每个人都拥有的技能,如果你取消注释最后一个 Employee,结果将是 null。
[Test]
public void GetSomeSkills()
{
var employees = new List<Employee>
{
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 2, Name = "C#" } } },
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 2, Name = "C#" } } },
// new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" } } },
};
bool HasSameSkills(Employee first, Employee second)
{
var firstIds = first.Skills.Select(x => x.Id).OrderBy(x => x).ToList();
var secondIds = second.Skills.Select(x => x.Id).OrderBy(x => x).ToList();
return firstIds.SequenceEqual(secondIds);
}
var commonSkills = employees.FirstOrDefault(x => employees.All(y => HasSameSkills(x, y)))?.Skills;
Console.WriteLine(string.Join(", ", (commonSkills ?? new List<Skills>()).Select(x => x.Name)));
// Output: Java, C#
}
我正在锻炼一项任务。基本上我在 C# 代码端得到了 3 个不同的列表。 Class 员工包含技能列表。还有员工名单。
例如:
class Employee
{
List<Skills> Skills;
}
class Skills
{
int Id;
int Name;
}
class Where_Im_Working_Currently
{
List<Employee> employees ;
}
我想要实现的是从每个人那里获得共同技能的列表。假设我们有 3 名员工,所有 3 名员工都有 JAVA 共同技能,例如 { id = x , name = JAVA }.
因此3名员工的技能都相似,需要提取id和name。
注意:我正在尝试获得所有匹配技能,而不仅仅是技能的子集
for e.g.
Case 1: Perfect match. (Get List having a, b, c)
list 1 => a, b, c
list 2 => a, b, c
list 3 => a, b, c
Case 1: No match. (Get Null list)
list 1 => a, b, c
list 2 => a, b,
list 3 => b, c
以下是我提出的查询:
var skills= employees.Select(x => x.Skills.Select(p => p.Id== x.Skill[0].Id && p.Name == x.Skill[0].Name));
但这会给 IEnumerable 带来错误,我无法形成 LINQ。
欢迎任何指点或帮助。
这可能不是最优化的方法,但这里有一个解决方案,可以输出所有员工共有的技能。
关键是使用 SelectMany
获取子列表。
public class Employee
{
public List<Skills> Skills { get; set; }
}
public class Skills
{
public int Id { get; set; }
public string Name { get; set; }
}
[Test]
public void GetSomeSkills()
{
var employees = new List<Employee>
{
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 2, Name = "C#" } } },
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 3, Name = "Cooking" } } },
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" } } },
//new Employee { Skills = new List<Skills> { new Skills { Id = 4, Name = "C++" } } }
};
var allSkills = employees.SelectMany(x => x.Skills).ToList();
Console.WriteLine(string.Join(", ", allSkills.Select(x => x.Name)));
// Output: Java, C#, Java, Cooking, Java
var commonSkills = employees.SelectMany(e =>
e.Skills.Where(s => employees.All(e2 => e2.Skills.Select(x => x.Id).Contains(s.Id)))).ToList();
Console.WriteLine(string.Join(", ", commonSkills.Select(x => x.Name)));
// Output: Java, Java, Java
}
如果您取消对最后一位员工的注释,您的结果将为零,因为不再有一项对所有员工都通用的技能。
您可能还想获得不同的结果,但听起来您已经知道该怎么做。
修改原始问题后编辑:
下面只输出每个人都拥有的技能,如果你取消注释最后一个 Employee,结果将是 null。
[Test]
public void GetSomeSkills()
{
var employees = new List<Employee>
{
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 2, Name = "C#" } } },
new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" }, new Skills { Id = 2, Name = "C#" } } },
// new Employee { Skills = new List<Skills> { new Skills { Id = 1, Name = "Java" } } },
};
bool HasSameSkills(Employee first, Employee second)
{
var firstIds = first.Skills.Select(x => x.Id).OrderBy(x => x).ToList();
var secondIds = second.Skills.Select(x => x.Id).OrderBy(x => x).ToList();
return firstIds.SequenceEqual(secondIds);
}
var commonSkills = employees.FirstOrDefault(x => employees.All(y => HasSameSkills(x, y)))?.Skills;
Console.WriteLine(string.Join(", ", (commonSkills ?? new List<Skills>()).Select(x => x.Name)));
// Output: Java, C#
}