如何快速匹配不同顺序的名称(fname,lname)与全名c#
How to quickly match names (fname, lname) in different order with full name c#
我正在尝试优化此 linq 查询。我想用快速常量(最好)检索值来替换此查询。我想到了一个双键字典,但我不知道 fname 或 lname 的顺序是第一个。想问问这里有没有快速的方法
我想获取一个名称列表,在其中搜索 fname-lname
,-
是分隔符,return 所有与搜索到的全名匹配的内容。人员名单可能会比较大。
var nameList = from p in listOfPeople
where ((p.lname+"-"+p.fname == fullName)
|| (p.fname+"-"+p.lname == fullname))
select p;
编辑:listOfPeople
可以是任何数据类型,不一定是列表。
在你的 "P" 定义中,我猜它是一个 "People" 类型,我会添加一个 "FullName" 属性,这将是你的比较器:
public string FullName {get {return fname + "-" + lname;}}
并修改您的 LINQ:
Where string.Equals(p.FullName, fullName)
.
如果您真的想使用任何数据类型,其中仅包括字符串甚至 DataTable,我真的没有看到比您使用的方法更好的方法...
以下是创建字典的方法。
var nameLookup = new Dictionary<Tuple<string,string>, List<Person>>();
foreach(var person in listOfPeople)
{
List<Person> people = null;
var firstLast = Tuple.Create(person.fname, person.lname);
if(nameLookup.TryGetValue(firstLast, out people))
{
people.Add(person);
}
else
{
nameLookup.Add(firstLast, new List<Person> { person });
}
// If the person's first and last name are the same we don't want to add them twice.
if(person.fname == person.lname)
{
continue;
}
var lastFirst = Tuple.Create(person.lname, person.fname);
if(nameLookup.TryGetValue(lastFirst, out people))
{
people.Add(person);
}
else
{
nameLookup.Add(lastFirst, new List<Person> { person });
}
}
那么您的查找将是
// split by the delimiter to get these if needed
var fullName = Tuple.Create(firstName, lastName);
List<Person> nameList = null;
if(!nameLookup.TryGetValue(fullName, out nameList))
{
nameList = new List<Person>();
}
将名字和姓氏分开很重要,否则您必须选择一个不会显示名字或姓氏的分隔符。连字符“-”可以是名字或姓氏的一部分。如果保证分隔符不属于名字或姓氏的一部分,您只需将 Tuple.Create(x,y)
的使用替换为 x + delimiter + y
并将字典更改为 Dictionary<string, List<Person>>
.
此外,将 List<Person>
作为字典值的原因是为了处理像 "Gary William" 和 "William Gary" 是两个不同的人的情况。
我用 Stopwatch 测试过,这似乎更有效一些
var nameList = from n in(
from p in listOfPeople
select new{FullName = p.fname +"-"+ p.lname}
)
where n.FullName==fullName
select n;
我正在尝试优化此 linq 查询。我想用快速常量(最好)检索值来替换此查询。我想到了一个双键字典,但我不知道 fname 或 lname 的顺序是第一个。想问问这里有没有快速的方法
我想获取一个名称列表,在其中搜索 fname-lname
,-
是分隔符,return 所有与搜索到的全名匹配的内容。人员名单可能会比较大。
var nameList = from p in listOfPeople
where ((p.lname+"-"+p.fname == fullName)
|| (p.fname+"-"+p.lname == fullname))
select p;
编辑:listOfPeople
可以是任何数据类型,不一定是列表。
在你的 "P" 定义中,我猜它是一个 "People" 类型,我会添加一个 "FullName" 属性,这将是你的比较器:
public string FullName {get {return fname + "-" + lname;}}
并修改您的 LINQ:
Where string.Equals(p.FullName, fullName)
.
如果您真的想使用任何数据类型,其中仅包括字符串甚至 DataTable,我真的没有看到比您使用的方法更好的方法...
以下是创建字典的方法。
var nameLookup = new Dictionary<Tuple<string,string>, List<Person>>();
foreach(var person in listOfPeople)
{
List<Person> people = null;
var firstLast = Tuple.Create(person.fname, person.lname);
if(nameLookup.TryGetValue(firstLast, out people))
{
people.Add(person);
}
else
{
nameLookup.Add(firstLast, new List<Person> { person });
}
// If the person's first and last name are the same we don't want to add them twice.
if(person.fname == person.lname)
{
continue;
}
var lastFirst = Tuple.Create(person.lname, person.fname);
if(nameLookup.TryGetValue(lastFirst, out people))
{
people.Add(person);
}
else
{
nameLookup.Add(lastFirst, new List<Person> { person });
}
}
那么您的查找将是
// split by the delimiter to get these if needed
var fullName = Tuple.Create(firstName, lastName);
List<Person> nameList = null;
if(!nameLookup.TryGetValue(fullName, out nameList))
{
nameList = new List<Person>();
}
将名字和姓氏分开很重要,否则您必须选择一个不会显示名字或姓氏的分隔符。连字符“-”可以是名字或姓氏的一部分。如果保证分隔符不属于名字或姓氏的一部分,您只需将 Tuple.Create(x,y)
的使用替换为 x + delimiter + y
并将字典更改为 Dictionary<string, List<Person>>
.
此外,将 List<Person>
作为字典值的原因是为了处理像 "Gary William" 和 "William Gary" 是两个不同的人的情况。
我用 Stopwatch 测试过,这似乎更有效一些
var nameList = from n in(
from p in listOfPeople
select new{FullName = p.fname +"-"+ p.lname}
)
where n.FullName==fullName
select n;