Menu
CoddyTech

Custom Sorting

Part of the Logic & Flow section of Coddy's GDScript journey. Lesson 51 of 78.

sort() puts an array in ascending order and changes the array itself. Numbers go from smallest to largest, and strings follow the same order as min(), capitals first. reverse() then gives descending order:

var scores := [40, 95, 12, 70]
scores.sort()
print(scores) # [12, 40, 70, 95]
scores.reverse()
print(scores) # [95, 70, 40, 12]

For any other order, call sort_custom() with a comparison function. It receives two elements, a and b, and returns true when a must come before b. Pass the function by its name, without parentheses:

func by_length(a: String, b: String) -> bool:
	return a.length() < b.length()

func _ready():
	var words := ["banana", "fig", "kiwi"]
	words.sort_custom(by_length)
	print(words) # ["fig", "kiwi", "banana"]

The comparison can look inside the elements. This one puts the dictionary with the most "hp" first:

func by_hp(a: Dictionary, b: Dictionary) -> bool:
	return a["hp"] > b["hp"]

The sort is not stable: elements that compare as equal can end up in any order. When ties matter, compare a second field when the first one is equal:

func by_score_then_name(a: Dictionary, b: Dictionary) -> bool:
	if a["score"] != b["score"]:
		return a["score"] > b["score"]
	return a["player"] < b["player"]

sort_custom() exists on Array, but not on the PackedStringArray that split() returns, so convert it first with Array(...). You will also meet the comparison written inline, as in sort_custom(func(a, b): return a > b). That form is a lambda, covered in the Advanced Functions chapter.

challenge icon

Challenge

Easy

The program reads two lines: whole numbers separated by spaces, and words separated by spaces. The given code stores them in numbers (an array of ints) and words (an array of strings).

  1. Write a comparison function by_length(a: String, b: String) -> bool at the top level. A shorter word comes first, and words of the same length are in alphabetical order.
  2. Print four lines: the numbers in ascending order, the numbers in descending order, the words in alphabetical order (with sort()), and the words sorted with sort_custom(by_length).

For the inputs 5 3 8 1 2 and elephant cat dolphin bee, the output is:

Ascending: [1, 2, 3, 5, 8]
Descending: [8, 5, 3, 2, 1]
Alphabetical: ["bee", "cat", "dolphin", "elephant"]
By length: ["bee", "cat", "dolphin", "elephant"]

Try it yourself

extends Node

# Write the comparison function by_length() here

func _ready():
	var numbers: Array[int] = []
	for text in OS.read_string_from_stdin().split(" ", false):
		numbers.append(int(text))
	var words := Array(OS.read_string_from_stdin().split(" ", false))
	# Sort the arrays and print the four lines
	pass
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow

Practice on your own: Online GDScript compiler