Simplest way to get the top n elements of a Scala Iterable
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Getting the top n elements from a Scala Iterable is easy if you are clear about what "top" means. In most cases it means the largest values according to the default ordering, but in real code you often need custom ordering, stable handling of ties, and an approach that matches the size of your data.
The Straightforward Approach
If the collection is small or readability matters more than micro-optimization, sort it and take the last n items. That is the simplest code and is often good enough.
There are two details worth noting:
- '
sortedreturns ascending order by default.' - '
takeRight(n)gives the largestnelements, andreversemakes the result descending.'
This works for any collection whose element type has an implicit Ordering.
Using sortBy for Case Classes
Real applications often work with objects, not raw numbers. In that case, choose the ranking field explicitly with sortBy.
This is still easy to read and makes the ranking rule obvious. For application code, that explicitness is valuable.
A Better Option When n Is Small
Sorting the whole collection costs more than necessary when you only need a few top elements from a very large input. In that case, a priority queue is more efficient because it avoids fully ordering every item.
This keeps only the best n values seen so far. For large streams or big collections, that can be much cheaper than sorting everything.
Choosing the Right Collection Method
There is no single best method for every situation:
- use
sorted.takeRight(n).reversefor clarity - use
sortBywhen ranking by a property - use a priority queue when performance matters and
nis small relative to the collection size
Another option is maxBy or max, but those return only one value. If you need several top elements, they are not the right tool unless you build extra logic around them.
If you want the result in ascending order among the winners, skip the final reverse step. The result shape depends on how the next part of your code consumes it.
Handling Custom Ordering
Sometimes "top" does not mean numerically largest. You may want highest score, shortest duration, or most recent timestamp. Scala's Ordering.by makes that explicit.
This is useful when you want sorted to work directly on your own type.
Common Pitfalls
The most common mistake is forgetting that sorted is ascending. Developers often write numbers.sorted.take(3) and accidentally get the three smallest elements instead of the three largest.
Another issue is assuming Iterable preserves order. Some implementations, such as Set, do not provide a stable insertion order. If tie behavior matters, convert to a sequence and define the ordering explicitly.
Be careful with large datasets. Full sorting is simple, but it does unnecessary work when you only need a tiny top slice. If performance becomes important, switch to a heap-based approach instead of repeatedly re-sorting.
Finally, think about duplicates. If you need the top n distinct values, add .distinct before sorting or use logic that enforces uniqueness. Otherwise, repeated values are preserved, which may or may not match the requirement.
Summary
- The simplest Scala solution is
sorted.takeRight(n).reverse. - Use
sortBywhen selecting top elements by a field on an object. - Use a priority queue for large inputs when
nis small. - Remember that
sortedis ascending by default. - Decide early whether duplicates, ordering stability, and tie behavior matter for your use case.

