在不使用foreach循环的情况下查找列表中的对象

4
我有一个以下类Student的列表。
class student
{
   Guid id;
   string name;
}
  • 该列表包含多个学生。要搜索具有特定ID的学生,我需要使用foreach循环并比较每个学生的ID。
  • 我正在寻找除foreach循环之外的更好替代方案。是否有其他可用的选择?
  • [编辑]:我所指的更好的替代方案是执行时间和性能优化的解决方案。
  • [编辑2] 另一个变化,如果id是Guid呢?
  • 谢谢,
  • Ram

如果是Guid,则为Dictionary<Guid, Student> - Saeb Amini
正如@Saeb所提到的,id是Guid还是int并不是很重要。只需相应地声明字典即可。 - Fredrik Mörk
6个回答

6

如果每个学生只能在列表中出现一次,你可能会想使用一个Dictionary<int, stutent>来代替。这样,您就可以通过ID高效地查找学生。

Dictionary<int, student> students = GetSomeStudents();

// locate student with id = 42
if (students.ContainsKey(42))
{
    var student = students[42];
    // do something useful
}

+1. 他也可以使用 List<>.Contains,但值得注意的是,除非 student 实现了 IComparable<>,否则这只是一个引用比较。 - Moo-Juice
学生不是一种类型吧?它是一个字符串。所以Dictionary<int, string>更有可能是更好的选择,对吧? - SkonJeet
@SkonJeet,根据OP的问题,student是一个类,因此它是一种类型,即引用类型。 - Saeb Amini
@Moo-Juice,List<T>.Contains的速度要慢得多,因为它需要枚举整个集合来查找匹配项。实际上,在大O符号表示法中,List<T>.Contains的搜索时间是O(n),而对于Dictionary<K,V>.ContainsKey,它是O(1) - Saeb Amini
@Saeb - 是的,但是学生类包括一个整数和一个字符串。如果您要将此整数作为字典键,则剩下的只有字符串作为值了吗? - SkonJeet
显示剩余3条评论

5

事实上,你必须迭代列表才能解决问题。但是,你可以使用LINQ:

List<Student> studentsList = ReadStudentsList();
var student = studentsList.Where(s => s.id == ID_IM_LOOKING_FOR).Single();

根据@Fredrik Mörk的回答,这可以简化为:

var student = studentsList.Single(s => s.id == ID_IM_LOOKING_FOR);

还要注意,如果没有找到学生,则Single()会抛出异常。如果你希望返回null,请使用SingleOrDefault()
但是,你实际上想要做的是将你的学生存储在一个映射中:
Dictionary<int, Student> students = ReadStudentsMap();
var student = students[ID_IM_LOOKING_FOR];

这比查找列表的性能要好得多(哈希表的O(1),树的O(log(n)))!


2

1

LINQ是一种选择,如果您不想使用foreach循环,那么您的代码将如下所示

var student = studentsList.FirstOrDefault(s => s.id == ID_IM_LOOKING_FOR);

0

您可以使用任何使用哈希查找的集合,因为它们的成员查找非常快。例如:Dictionary<K,V>OrderedDictionary。还有非泛型的Hashtable,但由于泛型的Dictionary<K,V>,它大多数情况下都是多余的。在大O符号表示法中,这些集合按键检索元素的时间为O(1),这是最好的。

为了访问元素,为了不产生两个查找的成本,而不是使用ContainsKey,您可以使用TryGetValue方法,例如:

Dictionary<Guid, Student> students = GetStudents();

Student student;
if (students.TryGetValue(guid, out student))
{
    // found
}

顺便提一下,OrderedDictionary 还允许您通过索引访问元素。


0

这里有一个想法,可以避免迭代列表:

  • 按照学生ID对列表进行排序
  • 实现更复杂的搜索算法(例如二分查找二分查找

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接