Reputation: 18485
After reading the example of Microsoft here
var query = from Student student in arrList
where student.Scores[0] > 95
select student;
foreach (Student s in query)
Console.WriteLine(s.LastName + ": " + s.Scores[0]);
I have a question :
Is it possible to avoid the loop ?
foreach (Student s in query)
Console.WriteLine(s.LastName + ": " + s.Scores[0]);
What if i rewrite the query and assume my query will always return one result.
var query = from Student student in arrList
where student.FirstName == "Cesar"
select student;
I dont need to do a loop... I know that my query return only one element.
Upvotes: 0
Views: 109
Reputation: 17274
It will still be an IEnumerable
, but with one item. If you want to extract it you can use First() or even better Single():
var query = from Student student in arrList
where student.FirstName == "Cesar"
select student;
var student = query.Single();
Also you can replace the entire where
clause by using Single/First
overloaded methods:
var emperor = arrList.Single(s => s.FirstName == "Cesar");
Single
is more strict than First
since it will also check that there is exactly one item returned.
Upvotes: 4
Reputation: 1536
Assuming only one result will be returned can be dangerous. What is more than one student scores over 95?
You can use a lambda expression, to compress your code:
arrList.ForEach(s => Console.WriteLine(s.LastName + ": " + s.Scores.First());
Upvotes: 0
Reputation: 21727
You can use the FirstOrDefault() method.
Here's your query, re-written...
var student = (from Student student in arrList
where student.FirstName == "Cesar"
select student).FirstOrDefault();
Your query can also be written, chaining methods. In my opinion, it's easier on the eyes...
arrList.Where(student => student.FirstName == "Cesar").FirstOrDefault();
Or even more condensed...
arrList.FirstOrDefault(student => student.FirstName == "Cesar");
Upvotes: 0
Reputation: 125538
query will be an IEnumerable<Student>
in this instance.
IEnumerable<T>
itself does not have an extension method that allows you to perform an action on each enumerated T
, like for example, List<T>
does with ForEach<T>(Action<T>)
. You can certainly write the extension method to do this and I am sure many people have, but it was a design decision to not have it (an article by Eric Lippert that discusses this).
If you know that your expression will always return one result then you can call .First()
on the projected collection (assuming you know there will always be at least one result).
var query = (from Student student in arrList
where student.Scores[0] > 95
select student).First();
Console.WriteLine(query.LastName + ": " + query.Scores[0]);
Upvotes: 0
Reputation: 676
For part 2 of your question, you can explicitly return a single Student object:
var student = (from Student s in arrList where s.FirstName == "Cesar" select student).FirstOrDefault();
Upvotes: 0
Reputation: 1554
In the lambda way
arrList.SingleOrDefault(q => q.Scores[0] > 95);
Upvotes: 0
Reputation: 19601
You can absolutely avoid calling the loop, if you know that there is only going to be 1 record/object returned.
Have a look at the .First()
, .FirstOrDefault()
, .Single()
, SingleOrDefault()
extension methods.
Upvotes: 0
Reputation: 2065
FirstOrDefault, I prefer the method chain syntax, such as,
arrList.FirstOrDefault(s => s.FirstName == "Cesar");
Upvotes: 3
Reputation: 6612
var query = from Student student in arrList
where student.FirstName == "Cesar"
select student;
use this query.First().LastName
if (query.Count() > 0)
Console.WriteLine(query.First().LastName + ": " + query.First().Scores[0]);
Upvotes: 0