Sort_by for custom sorting in Ruby - Time & Space Complexity
When we use sort_by in Ruby, it helps us sort items based on a custom rule.
We want to know how the time it takes to sort grows as we have more items.
Analyze the time complexity of the following code snippet.
items = ["apple", "banana", "pear", "grape"]
sorted = items.sort_by { |item| item.length }
puts sorted
This code sorts a list of words by their length using sort_by.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The sorting process compares items based on their length.
- How many times: It compares items multiple times, roughly proportional to the number of items times the logarithm of that number.
As the list gets bigger, the number of comparisons grows faster than just the number of items.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 30 comparisons |
| 100 | About 700 comparisons |
| 1000 | About 10,000 comparisons |
Pattern observation: The work grows a bit faster than the list size, but not as fast as the square of the size.
Time Complexity: O(n log n)
This means that if you double the number of items, the time to sort grows a bit more than double, but much less than square.
[X] Wrong: "Sorting with sort_by takes the same time no matter how many items there are."
[OK] Correct: Sorting needs to compare items, and more items mean more comparisons, so time grows as the list grows.
Understanding how sorting time grows helps you explain your code choices clearly and shows you know how your program behaves with bigger data.
"What if the block inside sort_by was more complex and took longer to run for each item? How would that affect the time complexity?"
Practice
sort_by do?Solution
Step 1: Understand the purpose of
sort_bysort_bysorts elements by a value you choose for each element, like length or age.Step 2: Compare with other array methods
Unlikesort!,sort_byreturns a new sorted array without changing the original.Final Answer:
Sorts elements based on a value you specify for each element. -> Option AQuick Check:
sort_by sorts by chosen value [OK]
- Thinking sort_by changes the original array
- Confusing sort_by with reverse or uniq
- Assuming sort_by removes duplicates
words by their length using sort_by?Solution
Step 1: Recall Ruby block syntax for sort_by
The correct syntax uses a block with curly braces and a block variable:array.sort_by { |item| expression }.Step 2: Match syntax with the options
words.sort_by { |word| word.length } correctly useswords.sort_by { |word| word.length }. Others have syntax errors or wrong usage.Final Answer:
words.sort_by { |word| word.length } -> Option CQuick Check:
sort_by needs a block with |variable| [OK]
- Passing arguments directly instead of using a block
- Using => instead of block braces
- Misplacing parentheses around block
people = [{name: "Anna", age: 30}, {name: "Bob", age: 25}, {name: "Cara", age: 35}]
sorted = people.sort_by { |person| person[:age] }
puts sorted.map { |p| p[:name] }Solution
Step 1: Understand sorting by age
The array is sorted by the :age key in ascending order: 25, 30, 35.Step 2: Map sorted array to names
After sorting, the order is Bob (25), Anna (30), Cara (35). Mapping names gives ["Bob", "Anna", "Cara"].Final Answer:
["Bob", "Anna", "Cara"] -> Option BQuick Check:
sort_by age ascending = [Bob, Anna, Cara] [OK]
- Assuming sort_by sorts descending by default
- Confusing keys in hash access
- Not mapping to names after sorting
items = ["apple", "pear", "banana"] sorted = items.sort_by do |item| item.length end puts sorted
Solution
Step 1: Check block syntax
The block usesdo |item| ... end, which is valid for sort_by.Step 2: Verify sort_by usage
sort_by accepts a block and returns a new array sorted by item length. No syntax or logic errors.Final Answer:
No error; code works correctly -> Option AQuick Check:
sort_by with do-end block is valid [OK]
- Thinking parentheses are mandatory around block
- Confusing sort_by with sort!
- Assuming sort_by modifies original array
products = [
{name: "Pen", price: 1.5, stock: 10},
{name: "Notebook", price: 2.0, stock: 0},
{name: "Eraser", price: 0.5, stock: 5}
]
How would you use sort_by to get products sorted by price but only include those with stock greater than zero?Solution
Step 1: Filter products with stock > 0
Useselectto keep only products wherestockis greater than zero.Step 2: Sort filtered products by price
Applysort_byon the filtered array to sort byprice.Final Answer:
products.select { |p| p[:stock] > 0 }.sort_by { |p| p[:price] } -> Option DQuick Check:
Filter then sort_by for correct result [OK]
- Trying to filter inside sort_by block
- Sorting by stock instead of price
- Selecting after sorting, which keeps unwanted items
Ready to prove it?
Pass the test and this pattern moves unknown
