从3个不同列表中获取匹配对象的列表

发布于 2025-02-02 23:59:59 字数 967 浏览 2 评论 0原文

我正在锻炼一项任务。基本上,我在C#代码方面有3个不同的列表。班级员工包含技能清单。并且还有员工名单。

例如:

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相似的技能,并且需要拿出名称。

注意:我正在尝试获得所有匹配的技能,而不仅仅是技能的子集

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

但这将使Inumerble可以使它变得错误,而我无法形成Linq 。

欢迎任何指针或帮助。

I'm exercising on one task. Basically i got 3 different lists in C# code side. Class employee is containing the skills list. And also have list of employees as well.

for example :

class Employee
{
   List<Skills> Skills;
}

class Skills
{
   int Id;
   int Name;
}

class Where_Im_Working_Currently
{
   List<Employee> employees ;
}

What I'm trying to achieve is to get list of common skills from every individual. suppose we have 3 employees and all 3 employees have JAVA skill in common such that { id = x , name = JAVA }.

so all 3 employees have skills similar with id and name needs to be fetched out.

NOTE : I'm trying to get all matching skills and not just subset of skills

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

following is the query i have come up with :

var skills= employees.Select(x => x.Skills.Select(p => p.Id== x.Skill[0].Id && p.Name == x.Skill[0].Name));

but this will give IEnumerable that's where its getting wrong and im unable to form LINQ.

Any pointers or help are welcomed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

渔村楼浪 2025-02-09 23:59:59

这可能不是最优化的方法,但是这里有一个解决方案,可以输出所有员工常见的技能。

关键是使用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
}

如果您不使用最后一个员工,您将获得零结果,因为不再有所有员工常见的技能。

您也可能想获得明显的结果,但听起来您已经知道该怎么做。

对原始问题进行修改后的编辑:

下面的输出只能每个人拥有的技能,如果您输入最后一名员工,则结果是无效的。

[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#
}

This might not be the most optimized way of doing this, but here's a solution that outputs the skills that are common for all employees.

The key is to use SelectMany to get to the child lists.

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
}

If you uncomment the last Employee you would have a zero result, as there would no longer be a skill that is common for all employees.

Also you probably want to get distinct result, but it sounds like you already know how to do that.

Edit after original question was modified:

The below outputs only the skills that everyone has, if you uncomment the last Employee you would have null as result.

[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#
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文