Sort array by two values priorizing one of them?

Here with another question! So, how can I sort an array by two values, priorizing one of them?

I’m doing some draw functions in a tilemap, but the placed tiles list doesn’t come ordered by their position. So I’m trying to do that, but I’m having trouble adapting solutions to this problem to Godot’s sort_custom, since it’s a Vector2.

So for example, an array that looks like this:
[(1,1), (1,0), (0,1), (0,0)]
Should look like this:
[(0,0), (1,0), (0,1), (1,1)]
AKA, from top to bottom, left to right

You may have to use this method:

void sort_custom(func: Callable)

Here is the doc with example how to create a callable.

I fought with this a bit but this seems to work. (But I’d bet there is a better way)
Note: MAX_VALUE must be equal to or greater than the highest value y can be in all the sorted vectors.

	var a:Array[Vector2] = [
		Vector2(1,1), Vector2(1,0), Vector2(0,1), 
        Vector2(0,0), Vector2(2,1), Vector2(3,0)]  
	const MAX_VALUE:int = 10
	a.sort_custom(func(a, b):
		var aa:int = a[1] * MAX_VALUE + a[0]
		var bb:int = b[1] * MAX_VALUE + b[0]
			
		return aa < bb
	)
[(1.0, 1.0), (1.0, 0.0), (0.0, 1.0), (0.0, 0.0), (2.0, 1.0), (3.0, 0.0)] # unsorted
[(0.0, 0.0), (1.0, 0.0), (3.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, 1.0)] # sorted

Lol, this twist also seems to work:

a.sort_custom(func(a, b):
	return str(a).reverse() < str(b).reverse()
)
1 Like

You can get the x and y components, you describe “top to bottom, left to right”, but your example here is “left to right, top to bottom”

If you want top to bottom, left to right aka [(0, 0), (0, 1), (1, 0), (1, 1)], then this will ensure the x value is lowest before checking y values.

func vector_sort(a: Vector2i, b: Vector2i) -> bool:
    if a.x == b.x:
		return a.y < b.y
    else:
        return a.x < b.x

array.sort_custom(vector_sort)

Doesn’t a standard sort of Vector2’s give you the same result?

var a:Array[Vector2] = [
		Vector2(1,1), Vector2(1,0), Vector2(0,1), Vector2(0,0), 
		Vector2(2,1), Vector2(3,0), Vector2(0,3)]
#presort:
[(1.0, 1.0), (1.0, 0.0), (0.0, 1.0), (0.0, 0.0), (2.0, 1.0), (3.0, 0.0), (0.0, 3.0)]
a.sort()
#post sort
[(0.0, 0.0), (0.0, 1.0), (0.0, 3.0), (1.0, 0.0), (1.0, 1.0), (2.0, 1.0), (3.0, 0.0)]
1 Like