An alternate way would be to use Twig's |filter() to do the filtering rather than Craft itself.
I can't say how much of a performance difference it makes, but I know that if you're doing very large queries many times, without adequate caching, it could slow your site down if you're constantly making multiple entry queries.
It also allows a bit more flexibility if you're trying to do something non-standard or need a function callback. For example, I wanted to create an array of IDs in Twig and then choose the first entry that matched it, and |filter() worked well in that situation.
{% set featured = [18, 56, 105] %}
{% set entries = craft.entries.section('myChosenSection').all() %}
{% set chosenEntry = entries|filter((entry) => entry.id in featured)|first %}
.first()in a single, however it seems if I remove it then the request returns nothing, as does using.find()- have I got something wrong in setup? – pumkincreative Jul 08 '14 at 14:49first()would still be necessary here. If you want to get an array of multiple entries back, it’sfind()that’s not necessary, sincefind()is the default behavior. – Brandon Kelly Jul 08 '14 at 14:54.first()is necessary? Since there is only one entry which matches the criteria. – Victor Jul 08 '14 at 17:01craft.entriesdoesn’t care whether it’s a Single or a Channel or a Structure. It’s only responsible for taking some parameters, passing them off to the ElementsService, and then either returning an array of all the results (find()) or just the first result (first()). You can technically usefind()with a Single section if you want; you’ll just get an array back of that one entry. – Brandon Kelly Jul 08 '14 at 19:21.slug()also requires.first()otherwise I can't seem to access any properties. ie.slug('my_slug').first();– Alexander Holsgrove May 18 '17 at 08:26