我有一个空列表,让我们说学生。在我在列表中插入学生之前,我想检查是否已经有一个具有相同ID的学生。
请注意,这是伪代码!
class Student
{
public int ID { get; set; } // ID is NOT unique
public string Name { get; set; }
public int Age { get; set; }
public List<Student> AddStudentsToList()
{
List<Student> students = new List<Student>();
foreach (Student student in source) // source is the place where the information comes from(text file, DB, etc.)
{
if (CompareStudents(students, student)) // Here's the place where I have to check if student with the current ID already exists in the list students(List<Student>)
{
students.Add(new Student(student));
}
}
return students;
}
private bool CompareStudents(List<Student> students, Student s) // Going through the whole list every time can't be the best solution, I think
{
bool duplicate = false;
foreach (var student in students)
{
if (student.ID == s.ID)
{
duplicate = true;
}
}
return duplicate;
}
}
我可以(以及如何)更有效地做到这一点吗?
注意:我需要跟踪重复项,因此Dictionary根本没有帮助。
答案 0 :(得分:2)
public void AddStudentsToList()
{
List<Student> students = new List<Student>();
HashSet<int> ids = new HashSet<int>();
foreach (Student student in source)
{
if (!ids.Add(student.ID))
{
students.Add(new Student(student));
}
}
}
顺便说一句,您可能希望从您的方法返回students
或使用某个字段/属性而不是局部变量来存储学生列表,否则方法毫无意义。
答案 1 :(得分:0)
找到副本后打破循环:
foreach (var student in students)
{
if (student.ID == s.ID)
{
duplicate = true;
break;
}
}
您可以使用Enumerable.Any
方法执行相同的操作:
return students.Any(student => student.ID == s.ID);
如果您想要更有效的解决方案,可以使用HashSet
return new HashSet<Student>(students).Count == students.Count;
这还需要覆盖您的课程的Equals
和GetHashCode
方法,如下所示:
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public override bool Equals(object obj)
{
return this.ID.Equals(((Student)obj).ID);
}
public override int GetHashCode()
{
return this.ID.GetHashCode();
}
}
另外,不要忘记将if语句更改为:
if (!CompareStudents(students, student))
如果存在重复,您的方法将返回 true ,因此您需要使用否定运算符,因为您只想在CompareStudents
返回 false 时执行添加。 / p>
答案 2 :(得分:0)
根据之后对象需要做的事情,这通常是HashTable
是集合对象的最佳选择时的一个主要示例 - 而不是List
。如果您以后需要按ID进行查找,那么Dictionary
集合可能是最佳选择。
知道何时选择正确的集合可以使您的代码更容易。更多信息:http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
答案 3 :(得分:0)
假设您使用的是.Net 3.5或更高版本,请使用generic HashSet代替列表,使用implement your own equals method来比较ID以及getHashcode方法。
如果元素已经存在,HashSet上的add方法将返回false。
答案 4 :(得分:0)
另一种可能性是使用Distinct
,但前提是您实施IEqualityComparer<Student>
或使Student
具有可比性:
class Student
{
public int ID { get; set; } // ID is NOT unique
public string Name { get; set; }
public int Age { get; set; }
public List<Student> AddStudentsToList()
{
var students = source.Distinct().ToList();
return students;
}
public override bool Equals(Student other)
{
var otherStudent = other as Student;
if (otherStudent == null)
{
return false;
}
return otherStudent.ID == this.ID;
}
public override int GetHashCode()
{
return this.ID.GetHashCode();
}
}
答案 5 :(得分:0)
好的,完全重写......
给出来自任意来源的学生数据列表 - 数据库,平面文件等 - 您可以使用LINQ查询或扩展以多种有趣的方式重新排列列表。
例如:
public class LoadedStudent
{
public int ID;
public Student Primary;
public Student[] Duplicates;
}
public List<LoadedStudent> LoadStudents(IEnumerable<Student> source)
{
var query =
from s in students
group s by s.ID into grp
let primary = grp.First()
select new LoadedStudent
{
ID = primary.ID,
Primary = primary,
Duplicates = grp.Skip(1).ToArray()
};
return Query.ToList();
}
从上面你可以得到一个由ID
组合在一起的所有已加载学生的列表,其中一个被选为主要,其余被放入一个数组。将导入列表转换为List<Student>
非常简单:
List<LoadedStudent> loadedstudents = LoadStudents(source);
List<Student> students = loadedstudents.Select(ls => ls.Primary).ToList();
您可以对其中一个列表执行其他处理,以确定谁有重复项等。
答案 6 :(得分:0)
List<Student> lstNumbers = new List<Student>();
Student studentInstance = new Student();
studentInstance.ID=1;
studentInstance.Name="Student1";
studentInstance.Age = 55;
Student testStudent = lstNumbers.Find(p => p.ID == studentInstance.ID);
if (testStudent == null)
{
lstNumbers.Add(studentInstance);
}
您可以使用上述代码之类的扩展方法,也可以使用LINQ查询来执行相同的操作。
答案 7 :(得分:0)
您可以使用Linq缩短代码购买支票ID,删除!在if()语句中,如果您只想将重复的学生添加到列表中。但由于你的名单最初是空的,你不会在那里添加任何学生,因为你找不到任何重复的学生。
public void AddStudentsToList()
{
List<Student> students = new List<Student>();
foreach (Student student in source)
{
if (!students.where(s => s.ID == student.ID).any())
{
students.Add(new Student(student));
}
}
}
答案 8 :(得分:0)
词典绝对是前进的方向。使用ContainsKey
确定您是否已拥有特定ID。如果没有,则将新的添加到字典中。如果您这样做,则将其存储在重复列表中。
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Dictionary<int, Student> students = new Dictionary<int, Student>();
List<Student> duplicates = new List<Student>();
private void ReadStudents(IEnumerable<Student> source)
{
// source could contain the same student more than once
foreach (Student student in source)
{
if (students.ContainsKey(student.ID))
duplicates.Add(student);
else
students[student.ID] = student;
}
}
public void Test()
{
List<Student> input = new List<Student>() {
new Student { ID=1, Name="Adam", Age=18 },
new Student { ID=2, Name="Bert", Age=18 },
new Student { ID=3, Name="Charlie", Age=19 },
new Student { ID=1, Name="Adam", Age=18 }, // duplicate
};
ReadStudents(input);
// 'students' now contains the list with duplicates removed
// 'duplicates' contains all the duplicates
}
答案 9 :(得分:0)
您可以实现IEqualityComparer
class Equalitycompare<T> : IEqualityComparer<T>
{
Func<T, T, bool> _equalsFunction;
Func<T, int> _hashCodeFunction;
public Equalitycompare( Func<T, T, bool> equalsFunction, Func<T, int> hashCodeFunction)
{
if (equalsFunction == null) throw new ArgumentNullException();
if (hashCodeFunction == null) throw new ArgumentNullException();
_equalsFunction = equalsFunction;
_hashCodeFunction = hashCodeFunction;
}
public bool Equals(T x, T y)
{
return _equalsFunction(x, y);
}
public int GetHashCode(T obj)
{
return _hashCodeFunction(obj);
}
}
static void Main(string[] args)
{
Student Student1 = new Student();
Student1.ID = 1;
Student Student2 = new Student();
Student2.ID = 1;
Student Student3 = new Student();
Student3.ID = 3;
var comparer = new Equalitycompare<Student>((x, y) => x.ID == y.ID, x => x.ID.GetHashCode());
var students = new List<Student>{Student1,Student2,Student3};
var uniquestudents = students.Distinct(comparer);
}
上查看这篇非常好的文章