Keep legal first and last names for formal lists; show DisplayFirstName on teams, calendars, and import matching so two Josiahs can be told apart. Co-authored-by: Cursor <cursoragent@cursor.com>
37 lines
1.0 KiB
C#
37 lines
1.0 KiB
C#
using Core.Entities;
|
|
using FuzzySharp;
|
|
|
|
namespace Core.Parsers;
|
|
|
|
/// <summary>
|
|
/// Fuzzy-matches a CSV or pasted name to existing students.
|
|
/// </summary>
|
|
public static class FuzzyStudentMatcher
|
|
{
|
|
public const int MatchThreshold = 90;
|
|
|
|
public static (Student Student, int Score)? Find(ICollection<Student> students, string name)
|
|
{
|
|
var ranked = students
|
|
.Select(s => (Student: s, Score: Score(s, name)))
|
|
.Where(x => x.Score >= MatchThreshold)
|
|
.OrderByDescending(x => x.Score)
|
|
.ToList();
|
|
|
|
return ranked.Count == 0 ? null : ranked[0];
|
|
}
|
|
|
|
public static int Score(Student student, string name)
|
|
{
|
|
var candidates = new[]
|
|
{
|
|
student.Name,
|
|
student.FirstNameLastName,
|
|
student.LastNameFirstName,
|
|
student.DisplayFirstName,
|
|
student.Nickname
|
|
}.Where(c => !string.IsNullOrWhiteSpace(c));
|
|
return candidates.Max(candidate => Math.Max(Fuzz.Ratio(candidate, name), Fuzz.TokenSetRatio(candidate, name)));
|
|
}
|
|
}
|