【问题标题】:.NET :- Matching object to Ojects in Hashset using linq.NET :- 使用 linq 将对象匹配到 Hashset 中的对象
【发布时间】:2020-11-06 10:14:18
【问题描述】:

目标是开发一个人力规划课程,将工作分配给员工 根据他们的技能。

  • 我们在以下任务(变量)中分配任务。

    IEnumerable<Task> task = repository.Tasks.ToList();
    

taskSmall 包含 TaskId 和 Skill Id:-

Id  SkillRequired
1   1
2   2
  • 现在我们有了人员列表

    IEnumerable<Person> people = repository.People.ToList();
    

其中 people 包含 Person NameHashSet&lt;Skill&gt; Skills 等字段。一个人可以拥有多种技能。

  • 问题是我们需要匹配来自task的任务所需的技能和来自HashSet的每个人的技能,并且我们需要在分配后检索TaskIdPerson Name

  • 每项任务都需要一个人来执行。如果任务重复需要技能,那么我们需要根据技能检查哪个人不忙(或没有分配任何任务)来完成该任务。

【问题讨论】:

  • 什么是taskSmall
  • 试试 IEqulityComparer : docs.microsoft.com/en-us/dotnet/api/…
  • 当您有技能 2 的任务和技能 1 的任务时,您想如何处理具有技能 1 和 2 的人 A、具有技能 1 的人 B?
  • @NetMage 如果您将具有技能 2 的任务分配给 A 人,那么他将很忙,而您离开另一个任务和 B 人。如果被排除在外的人有技能完成剩余任务,那么您应该分配他
  • 但是如果您按顺序分配任务,您可以将技能 1 的任务分配给 A 人,而没有人执行技能 2 的任务 - 我想您想避免这种情况吗?

标签: c# asp.net .net asp.net-mvc linq


【解决方案1】:

首先,我会将Person Skills 展平,以便每个人都有他们的一项技能:

var peopleSkill = people.SelectMany(p => p.Skills.Select(skill => new { skill, p }));

然后我会找到与任务所需技能相匹配的所有可能的人员集合,并按此人的技能数量排序,以便优先分配较少的技能人员:

var matchings = task.GroupJoin(peopleSkill,
                               t => t.SkillId,
                               ps => ps.skill.SkillId,
                               (task, pss) => new { task, people = pss.Select(ps => ps.p).OrderBy(p => p.Skills.Count) })
                    .OrderBy(tp => tp.people.Count());

然后您可以检查可能的分配并将第一个可用的人分配给每个任务:

var assigned = new Dictionary<Task, Person>();
var usedPeople = new HashSet<Person>();
foreach (var m in matchings) {
    foreach (var tryPerson in m.people) {
        if (!usedPeople.Contains(tryPerson)) {
            assigned.Add(m.task, tryPerson);
            usedPeople.Add(tryPerson);
            break;
        }
    }
}

这提供了所有任务的 IEnumerable,如果未分配,则与 Personnull 配对:

var ans = task.Select(t => new { task = t, person = assigned.TryGetValue(t, out var p) ? p : default });

【讨论】:

  • 你是对的,用 SkillId 加入表格,但我正在从 CSV 文件中读取数据。这样我们就没有PK和FK(外键)。没关系,但如果我们继续,任务会重复。
  • @ChrisJ 我不明白。 GroupJoin 不关心键,只关心告诉它应该匹配什么的 lambda 方法,它应该可以很好地处理来自 CSV 文件的数据。
猜你喜欢
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多