I want to sort a list of points in space - however, the area wraps around. So I want to take a starting point and sort points based on walking in one direction, wrapping back round to where I started.
Basically I’m pushing some crates that will appear through the edge of the map behind me as I push them through the edge of the map in front of me.
I must however move the crate in front of me last for obvious reasons. That’s why I need to sort the list of crates in this fashion.
I need to get the starting point of the wrapping sort into the function I’m feeding to table.sort(). I can think of some extremely hacky ways to do it (I’ve noticed the compiler doesn’t like a lot of my ideas in this direction). But I’m wondering if there’s a simple way to do this. I’ve looked up lots of examples of table.sort() and they only have anonymous function examples. I’ve tried to feed it a class function but it didn’t like the colon syntax. Which annoys me because I could have kept the logic for the sort internal to the class calling it.
I get it now with classes and self referencing, but what I was really asking was if there was a way to get persistent data into the anonymous function that is fed to table.sort.
I think there’s a way to do it with closures. I’ve put together a clunky example with my basic knowledge:
function setSort(a, b)
local c = a
return function(a, b)
print(a, b, c)
return a < b
end
end
test = setSort(5)
t = {4, 2, 1, 3, 4, 5}
table.sort(t, test)
print(table.concat(t, " "))
Can anyone with a better understanding of closures improve on this?
*edit
I’m guessing that technically I should be able to return an anonymous function from a class method and that sort function would have access to the class - right?
Ah, but MyClass.sort doesn’t have access to self. The colon syntax is shorthand:
obj:method(a, b)
-- actually calling:
obj.method(self, a, b)
Which is why a class function is inadmissible as a sort function. “self” isn’t an intrinsic property of the class. It’s passed into every function of an object secretly through the colon syntax. The function has to be declared in a scope where self exists. MyClass.sort won’t work because it has access to global scope and itself. Not the scope of the class where the boundaries to wrap around are defined.
This should work however:
function MyClass:init(bounds)
self.bounds = bounds
self.sort = function(a, b)
local ax = a.x
local bx = a.x
if ax < self.bounds then ax = ax + self.bounds end
if bx < self.bounds then bx = bx + self.bounds end
return ax < bx
end
end
The function is declared in a scope aware of self and bounds. I should be able to pass self.sort to table.sort. The class aware of the bounds is a Controller class for the crates - so I’m only likely to declare one at a time. Declaring in the crates would be a waste of memory, yes.
i didnt read in your post and example that you needed to access self.bounds, this is why i suggested MyClass.sort.
Your last example should work as you say.