[英]Finding object in List without using foreach
I have list of following class Student 我有以下班级学生名单
class student
{
Guid id;
string name;
}
The list contains multiple students. 该列表包含多个学生。 To search a student with specific id, I need to use foreach loop and compare id of each student.
要搜索具有特定ID的学生,我需要使用foreach循环并比较每个学生的ID。
I am looking for a better alternative instead of foreach loop. 我正在寻找一个更好的替代品而不是foreach循环。 Is there any alternative available?
有没有其他选择?
[EDIT]: What I meant by better alternative is optimized solution in terms of execution time and performance [编辑]:我所说的更好的替代方案是在执行时间和性能方面的优化解决方案
[EDIT2] One more twist, what if id is Guid. [EDIT2]还有一个转折,如果id是Guid怎么办?
Thanks, 谢谢,
Ram 内存
If each student
can appear in the list only once, you might want to use a Dictionary<int, stutent>
instead. 如果每个
student
只能在列表中出现一次,则可能需要使用Dictionary<int, stutent>
。 Then you will have a very efficient way of looking up students by id. 那么你将有一个非常有效的方式来查找id的学生。
Dictionary<int, student> students = GetSomeStudents();
// locate student with id = 42
if (students.ContainsKey(42))
{
var student = students[42];
// do something useful
}
Nothing will really change the fact that you have to iterate over the list. 没有什么能真正改变你必须遍历列表的事实。 But you can use LINQ:
但你可以使用LINQ:
List<Student> studentsList = ReadStudentsList();
var student = studentsList.Where(s => s.id == ID_IM_LOOKING_FOR).Single();
Based on an answer by @Fredrik Mörk, this could be shortened to: 根据@FredrikMörk的回答,这可以缩短为:
var student = studentsList.Single(s => s.id == ID_IM_LOOKING_FOR);
Also note, that Single()
will throw an exception, if no student is found. 另请注意,如果找不到学生,
Single()
将抛出异常。 If you'd prefer to just return null
, use SingleOrDefault()
. 如果您只想返回
null
,请使用SingleOrDefault()
。
But what you actually want to be doing is storing your students in a map: 但你真正想要做的是将学生存放在地图中:
Dictionary<int, Student> students = ReadStudentsMap();
var student = students[ID_IM_LOOKING_FOR];
This has a way better performance (O(1) for hashtables, O(log(n)) for trees) than looking through the list (O(n))! 这有一个更好的方式表现(O(1)哈希表,为O(log(n))的树木)比在列表中查找(O(n))的!
You can use LINQ: 您可以使用LINQ:
var student = students.SingleOrDefault(s => s.id == 12);
Enumerable.SingleOrDefault Method Enumerable.SingleOrDefault方法
如果您不想使用foreach lop,LINQ是可选项,因此您的代码将如下所示
var student = studentsList.FirstOrDefault(s => s.id == ID_IM_LOOKING_FOR);
Here's an idea, to avoid having to iterate over the list : 这是一个想法,以避免迭代列表:
You can use any collection that uses hash lookup because their member look up is very quick. 您可以使用任何使用哈希查找的集合,因为它们的成员查找速度非常快。 eg
Dictionary <K,V>
, OrderedDictionary
. 例如,
Dictionary <K,V>
, OrderedDictionary
。 There is also the nongeneric Hashtable
which is mostly rendered redundant by the generic Dictionary<K,V>
. 还有非泛型
Hashtable
,它通常由泛型Dictionary<K,V>
呈现为冗余。 In Big-O notation, element retrieval time by key for these collections is O(1)
, which is as good as it gets. 在Big-O表示法中,按键获取这些集合的元素检索时间为
O(1)
,这与它得到的一样好。
For accessing elements, to not incur the cost of two lookups, instead of using ContainsKey
, you can use the TryGetValue
method, eg: 要访问元素,不要使用两次查找,而不是使用
ContainsKey
,您可以使用TryGetValue
方法,例如:
Dictionary<Guid, Student> students = GetStudents();
Student student;
if (students.TryGetValue(guid, out student))
{
// found
}
BTW, OrderedDictionary
also allows you to access elements by index. BTW,
OrderedDictionary
还允许您通过索引访问元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.