使用c#3和.Net Framework 3.5,我有一个Person对象
public Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int SSN { get; set; }
}
我有一个列表:
List<Person> persons = GetPersons();
如何在列表中SSN不唯一的人员中获取所有Person对象,并将其从人员列表中删除,并理想地将其添加到另一个名为“List<Person> dupes
”的列表中?
原始列表可能如下所示:
persons = new List<Person>();
persons.Add(new Person { Id = 1,
FirstName = "Chris",
LastName="Columbus",
SSN=111223333 }); // Is a dupe
persons.Add(new Person { Id = 1,
FirstName = "E.E.",
LastName="Cummings",
SSN=987654321 });
persons.Add(new Person { Id = 1,
FirstName = "John",
LastName="Steinbeck",
SSN=111223333 }); // Is a dupe
persons.Add(new Person { Id = 1,
FirstName = "Yogi",
LastName="Berra",
SSN=123456789 });
最终结果是Cummings和Berra在原始人名单中,并且将Columbus和Steinbeck列入名为dupes的列表中。
非常感谢!
答案 0 :(得分:23)
这可以获得重复的SSN:
var duplicatedSSN =
from p in persons
group p by p.SSN into g
where g.Count() > 1
select g.Key;
重复列表如下:
var duplicated = persons.FindAll( p => duplicatedSSN.Contains(p.SSN) );
然后迭代重复项并删除它们。
duplicated.ForEach( dup => persons.Remove(dup) );
答案 1 :(得分:3)
感谢gcores帮助我开始了正确的道路。这就是我最终做的事情:
var duplicatedSSN =
from p in persons
group p by p.SSN into g
where g.Count() > 1
select g.Key;
var duplicates = new List<Person>();
foreach (var dupeSSN in duplicatedSSN)
{
foreach (var person in persons.FindAll(p => p.SSN == dupeSSN))
duplicates.Add(person);
}
duplicates.ForEach(dup => persons.Remove(dup));
答案 2 :(得分:1)
List<Person> actualPersons = persons.Distinct().ToList();
List<Person> duplicatePersons = persons.Except(actualPersons).ToList();
答案 3 :(得分:1)
基于上述@gcores的推荐。
如果要将重复SSN的单个对象添加回人员列表,请添加以下行:
IEnumerable<IGrouping<string, Person>> query = duplicated.GroupBy(d => d.SSN, d => d);
foreach (IGrouping<string, Person> duplicateGroup in query)
{
persons.Add(duplicateGroup .First());
}
我的假设是你可能只想删除重复值减去重复项的原始值。
答案 4 :(得分:0)
如果你像这样实现IComparable:
int IComparable<Person>.CompareTo(Person person)
{
return this.SSN.CompareTo(person.SSN);
}
然后进行如下比较:
for (Int32 i = 0; i < people.Count; i++)
{
for (Int32 j = 1; j < items.Count; j++)
{
if (i != j && items[i] == items[j])
{
// duplicate
}
}
}
答案 5 :(得分:0)
遍历列表并保留一个SSN /计数对的哈希表。然后枚举您的表并删除与SSN计数&gt;匹配的SSN匹配的项目0
Dictionary<string, int> ssnTable = new Dictionary<string, int>();
foreach (Person person in persons)
{
try
{
int count = ssnTable[person.SSN];
count++;
ssnTable[person.SSN] = count;
}
catch(Exception ex)
{
ssnTable.Add(person.SSN, 1);
}
}
// traverse ssnTable here and remove items where value of entry (item count) > 1
答案 6 :(得分:0)
persons
必须是List<Person>
吗?如果它是Dictionary<int, Person>
怎么办?
var persons = new Dictionary<int, Person>();
...
// For each person you want to add to the list:
var person = new Person
{
...
};
if (!persons.ContainsKey(person.SSN))
{
persons.Add(person.SSN, person);
}
// If you absolutely, positively got to have a List:
using System.Linq;
List<Person> personsList = persons.Values.ToList();
如果您正在使用Person
的唯一实例(而不是可能碰巧具有相同属性的不同实例),则使用HashSet
可能会获得更好的性能。