[英]How can I take objects from the second set of objects which don't exist in the first set of objects in fast way?
[英]How can I speed up existing code where I want to get objects from the first list which don't exist on the second list?
我有两种不同的列表( 因为它们在两个不同的数据库中代表两种不同的类型 ):
public partial class PersonOne
{
public int id { get; set; }
public string name { get; set; }
public string surname { get; set; }
public string address { get; set; }
public string phone { get; set; }
}
public partial class PersonTwo
{
public int id { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
public string email { get; set; }
}
我想消除列表上具有相同的名字和姓氏的重复项,然后从该列表中获取与列表上的对象具有不同的名字和姓氏的对象。 类PartTwo中的名=类PartOne中的名称,类PartTwo =类PartTwo中的姓。
我有该代码,但它非常慢:
List<PersonOne> personOneList = new List<PersonOne>(); // very big list
List<PersonTwo> personTwoList = new List<PersonTwo>(); // very big list
List<PersonTwo> difference = personTwoList
.GroupBy(x => new { FirstName = x.firstname.ToLower(), LastName = x.lastname.ToLower() })
.Select(x => x.First())
.Where(x => !personOneList.Any(y => y.name.Equals(x.firstname, StringComparison.InvariantCultureIgnoreCase) && y.surname.Equals(x.lastname, StringComparison.InvariantCultureIgnoreCase)))
.ToList();
尝试这个:
var HashTable = new Dictionary<Tuple<String,String>,Object>();
foreach (PersonOne person in personOneList)
{
var personTuple = Tuple.Create(person.name, person.surname);
if (!HashTable.ContainsKey(personTuple))
{
HashTable[personTuple] = person;
}
}
foreach (PersonTwo person in personTwoList)
{
var personTuple = Tuple.Create(person.firstname, person.lastname);
if (!HashTable.ContainsKey(personTuple)) {
HashTable[personTuple] = person;
}
}
var myResult = HashTable.Where(x => x.Value is PersonTwo).Select(x => x.Value).Cast<PersonTwo>().ToList();
HashTable(字典)简化了以下工作:(a)从列表中排除PersonOne类型的人,以及(b)删除第二个人的重复项。
第三,它在O(N)
时间而不是O(N^2)
。
首先,我建议您对Person使用单个类。 如果存在差异,则将父类作为Person并从Person继承PersonOne和PersonTwo。
对于您现有的设计,我建议您使用IEnumerable而不是List。 看看
Stopwatch sw = new Stopwatch();
sw.Start();
List<PersonTwo> difference = personTwoList
.GroupBy(x => new { FirstName = x.firstname.ToLower(), LastName = x.lastname.ToLower() })
.Select(x => x.First())
.Where(x => !personOneList.Any(y => y.name.Equals(x.firstname, StringComparison.InvariantCultureIgnoreCase) && y.surname.Equals(x.lastname, StringComparison.InvariantCultureIgnoreCase)))
.ToList();
sw.Stop();
Console.WriteLine("Time elapsed: {0}", sw.ElapsedTicks);//took 83333ms
Stopwatch sw1 = new Stopwatch();
sw1.Start();
IEnumerable<PersonTwo> difference1 = personTwoList
.GroupBy(x => new { FirstName = x.firstname.ToLower(), LastName = x.lastname.ToLower() })
.Select(x => x.First())
.Where(x => !personOneList.Any(y => y.name.Equals(x.firstname, StringComparison.InvariantCultureIgnoreCase) && y.surname.Equals(x.lastname, StringComparison.InvariantCultureIgnoreCase)));
sw1.Stop();
Console.WriteLine("Time elapsed: {0}", sw1.ElapsedTicks);//took 9ms
Console.ReadLine();
结果基于以下生成的测试数据
for (int i = 0; i < 500; i++)
{
personOneList.Add(new PersonOne
{
surname = "a" + i,
name = "b"+ i
});
personTwoList.Add(new PersonTwo
{
lastname = "a" + i,
firstname = "b" + i
});
}
for (int i = 0; i < 100; i++)
{
personTwoList.Add(new PersonTwo
{
lastname = "c" + i,
firstname = "d" + i
});
}
for (int i = 0; i < 100; i++)
{
personTwoList.Add(new PersonTwo
{
lastname = "a" + i,
firstname = "b" + i
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.