Bird
Raised Fist0
Rubyprogramming~10 mins

Sort_by for custom sorting in Ruby - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Sort_by for custom sorting
Start with array
↓
Apply sort_by block
↓
Transform each element to sort key
↓
Sort elements by keys
↓
Return sorted array
The array is transformed by a block to keys used for sorting, then sorted by those keys, returning a new sorted array.
Execution Sample
Ruby
words = ["apple", "pear", "banana"]
sorted = words.sort_by { |word| word.length }
puts sorted
Sorts the array of words by their length in ascending order.
Execution Table
StepElementSort Key (word.length)ActionResulting Array State
1"apple"5Calculate key["apple", "pear", "banana"]
2"pear"4Calculate key["apple", "pear", "banana"]
3"banana"6Calculate key["apple", "pear", "banana"]
4All keys calculated-Sort by keys["pear", "apple", "banana"]
5Return sorted array-Output sorted array["pear", "apple", "banana"]
💡 All elements transformed to keys and sorted by those keys, sorting ends.
Variable Tracker
VariableStartAfter 1After 2After 3Final
words["apple", "pear", "banana"]["apple", "pear", "banana"]["apple", "pear", "banana"]["apple", "pear", "banana"]["apple", "pear", "banana"]
sortednilnilnilnil["pear", "apple", "banana"]
Key Moments - 2 Insights
Why does sort_by use the block's return value instead of the element itself to sort?
sort_by transforms each element into a key using the block (see steps 1-3 in execution_table). It sorts by these keys, not the original elements, allowing custom sorting criteria.
Does sort_by change the original array?
No, as shown in variable_tracker, the original array 'words' stays the same. sort_by returns a new sorted array stored in 'sorted' (step 5).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 2, what is the sort key for "pear"?
A5
B4
C6
D3
💡 Hint
Check the 'Sort Key (word.length)' column at step 2 in execution_table.
At which step does the array get sorted by the keys?
AStep 4
BStep 2
CStep 3
DStep 5
💡 Hint
Look for the 'Action' column mentioning sorting in execution_table.
If we changed the block to sort by the last letter of each word, how would the sort keys change?
AKeys would be word lengths
BKeys would be the first character of each word
CKeys would be the last character of each word
DKeys would be the whole word
💡 Hint
sort_by uses the block return value as key; changing block changes keys (see concept_flow).
Concept Snapshot
sort_by { |element| key } transforms each element to a key
Sorts elements by these keys ascending
Returns new sorted array, original unchanged
Useful for custom sorting criteria
Example: array.sort_by { |x| x.length }
Full Transcript
This example shows how Ruby's sort_by method works. We start with an array of words. Each word is passed to the block, which returns the word's length as the sort key. The method collects these keys, then sorts the original elements by these keys. The original array remains unchanged. The result is a new array sorted by word length. This process is shown step-by-step in the execution table and variable tracker. Key moments clarify why sort_by uses keys and does not modify the original array. The quiz tests understanding of keys and sorting steps.

Practice

(1/5)
1. What does the Ruby method sort_by do?
easy
A. Sorts elements based on a value you specify for each element.
B. Changes the original array to a sorted one.
C. Removes duplicate elements from an array.
D. Reverses the order of elements in an array.

Solution

  1. Step 1: Understand the purpose of sort_by

    sort_by sorts elements by a value you choose for each element, like length or age.
  2. Step 2: Compare with other array methods

    Unlike sort!, sort_by returns a new sorted array without changing the original.
  3. Final Answer:

    Sorts elements based on a value you specify for each element. -> Option A
  4. Quick Check:

    sort_by sorts by chosen value [OK]
Hint: Remember: sort_by sorts by a custom value, not in-place [OK]
Common Mistakes:
  • Thinking sort_by changes the original array
  • Confusing sort_by with reverse or uniq
  • Assuming sort_by removes duplicates
2. Which of the following is the correct syntax to sort an array words by their length using sort_by?
easy
A. words.sort_by(word.length)
B. words.sort_by => word.length
C. words.sort_by { |word| word.length }
D. words.sort_by(word) { length }

Solution

  1. 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 }.
  2. Step 2: Match syntax with the options

    words.sort_by { |word| word.length } correctly uses words.sort_by { |word| word.length }. Others have syntax errors or wrong usage.
  3. Final Answer:

    words.sort_by { |word| word.length } -> Option C
  4. Quick Check:

    sort_by needs a block with |variable| [OK]
Hint: Use curly braces and |var| for sort_by blocks [OK]
Common Mistakes:
  • Passing arguments directly instead of using a block
  • Using => instead of block braces
  • Misplacing parentheses around block
3. What will be the output of this Ruby code?
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] }
medium
A. ["Anna", "Bob", "Cara"]
B. ["Bob", "Anna", "Cara"]
C. ["Cara", "Anna", "Bob"]
D. ["Bob", "Cara", "Anna"]

Solution

  1. Step 1: Understand sorting by age

    The array is sorted by the :age key in ascending order: 25, 30, 35.
  2. Step 2: Map sorted array to names

    After sorting, the order is Bob (25), Anna (30), Cara (35). Mapping names gives ["Bob", "Anna", "Cara"].
  3. Final Answer:

    ["Bob", "Anna", "Cara"] -> Option B
  4. Quick Check:

    sort_by age ascending = [Bob, Anna, Cara] [OK]
Hint: Sort_by returns new array sorted by block value [OK]
Common Mistakes:
  • Assuming sort_by sorts descending by default
  • Confusing keys in hash access
  • Not mapping to names after sorting
4. Identify the error in this code snippet:
items = ["apple", "pear", "banana"]
sorted = items.sort_by do |item|
  item.length
end
puts sorted
medium
A. No error; code works correctly
B. Incorrect block syntax for sort_by
C. Missing parentheses in sort_by call
D. Using sort_by instead of sort

Solution

  1. Step 1: Check block syntax

    The block uses do |item| ... end, which is valid for sort_by.
  2. 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.
  3. Final Answer:

    No error; code works correctly -> Option A
  4. Quick Check:

    sort_by with do-end block is valid [OK]
Hint: do-end blocks work fine with sort_by [OK]
Common Mistakes:
  • Thinking parentheses are mandatory around block
  • Confusing sort_by with sort!
  • Assuming sort_by modifies original array
5. Given an array of hashes representing products:
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?
hard
A. products.sort_by { |p| p[:stock] }.select { |p| p[:price] > 0 }
B. products.sort_by { |p| p[:price] if p[:stock] > 0 }
C. products.sort_by { |p| p[:stock] > 0 ? p[:price] : 0 }
D. products.select { |p| p[:stock] > 0 }.sort_by { |p| p[:price] }

Solution

  1. Step 1: Filter products with stock > 0

    Use select to keep only products where stock is greater than zero.
  2. Step 2: Sort filtered products by price

    Apply sort_by on the filtered array to sort by price.
  3. Final Answer:

    products.select { |p| p[:stock] > 0 }.sort_by { |p| p[:price] } -> Option D
  4. Quick Check:

    Filter then sort_by for correct result [OK]
Hint: Filter first, then sort_by for combined conditions [OK]
Common Mistakes:
  • Trying to filter inside sort_by block
  • Sorting by stock instead of price
  • Selecting after sorting, which keeps unwanted items
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard