Example:

Dictionary = {
"a", 5
"b", 3
"c", 4
}

=>

Dictionary = {
"a", 5
"c", 4
"b", 3
}

  • Container Make something like LeaderboardEntry class. Let it contain name and score properties. Keep a bunch of objects of this class in a regular array. This way you also get a system that's easily extended to store additional stats e.g. play time or level reached.

    Note that dictionary's primary purpose is to index elements via arbitrary type keys (aka mapping), which is totally not needed for score tables.

You can't really sort a Dictionary. The keys are not guaranteed to be stored in any particular order.

You can copy or print the keys and values in a specified order.

	var dict: Dictionary = {
		"a": 5,
		"b": 3,
		"c": 4,
	}

	var keys: Array = dict.keys()

	# Sort keys in descending order of values.
	keys.sort_custom(func(x: String, y: String) -> bool: return dict[x] > dict[y])

	for k: String in keys:
		print("key=", k, ", value=", dict[k])

Output:

key=a, value=5
key=c, value=4
key=b, value=3

The Array.sort_custom method is documented here:
https://docs.godotengine.org/en/4.2/classes/class_array.html#class-array-method-sort-custom

  • xyz replied to this.

    DaveTheCoder The keys are not guaranteed to be stored in any particular order

    I think in GDScript they actually are guaranteed to be stored in order of insertion. So it can be done the way you've shown plus re-insertion into a new dictionary. Although @Container if you've encountered a need to sort a dictionary, you're likely using an inadequate data structure for your problem.

      xyz

      Context:

      I want to make a local leaderboard system, and I used a Dictionary to store the playername and the player score.
      But of course, I wanted to sort them so that the best player appears at the top of the leaderboard.

        Container Make something like LeaderboardEntry class. Let it contain name and score properties. Keep a bunch of objects of this class in a regular array. This way you also get a system that's easily extended to store additional stats e.g. play time or level reached.

        Note that dictionary's primary purpose is to index elements via arbitrary type keys (aka mapping), which is totally not needed for score tables.

        Container But of course, I wanted to sort them so that the best player appears at the top of the leaderboard.

        Why "of course"? When a new leader emerges, rebuild the entire base? Also, the results of ordinary players will change. It doesn't matter what order the results are stored, it matters how they are displayed. As they say in Russia, "It doesn't matter how people vote (in elections), it matters who counts".

        xyz I think in GDScript they actually are guaranteed to be stored in order of insertion.

        The documentation states:

        Dictionaries will preserve the insertion order when adding new entries.

        https://docs.godotengine.org/en/4.2/classes/class_dictionary.html#description

        Assuming that's true, it's an odd specification. It limits potential improvements in the implementation.

        And then the following statement is:

        In other programming languages, this data structure is often referred to as a hash map or an associative array.

        That's somewhat contradictory, since in other programming languages, the insertion order might not be preserved.

        In any case, for a Dictionary, I don't think it's a good practice to write code that depends on the keys or values being in a particular order.

        • xyz replied to this.

          DaveTheCoder That's somewhat contradictory, since in other programming languages, the insertion order might not be preserved.

          I don't find it contradictory. The order really only matters when iterating over the elements. In languages like Python or GDScript, where the main container iteration mechanism is the for..in loop, it's better to have some guaranteed order convention rather than saying to coders; "well the order is just random, deal with it". This was, again, taken from Python where you can use OrderedDict that preserves the insertion order. I think that as of 3.7 this is guaranteed for regular Python dicts as well.

          Even C++ std::map guarantees the ordering, although it does it in a different way by sorting at insertion.

          I do agree though that building a system that depends on dictionary ordering might be a warning sign that one is not fully understanding what dicts are for and may be misusing them, as I already hinted in the previous post.