Wrap Sort anonymous function

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.

Any ideas?

I’d use two crates with identical values and rotate between the two…

If(Crate1.x + crate1.length >= WIDTH) then
Crate2 = Crate()
–copy all values for crate1
Crate2.x = WIDTH - (crate1.x + crate1.length)

If(Crate2.x + crate2.length >= WIDTH) then
Crate1 = Crate()
–copy all values for crate2
Crate1.x = WIDTH - (crate2.x + crate2.length)

So as one falls off another would start at the very beginning of the left of the screen…I’m not really a pro, but that’s how I’d do it

@st33d - maybe this will help


(Googling “class callback” may bring up more, this has been raised several times before)

If you want to pass a class function use


Edit: sorry Ignatz already said that

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

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?


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?

You could pass selfto the function from the class

@st33d yes that would work

MyClass = class()
function MyClass:getSort()
  return function(a,b) return a<b end

a = MyClass()

f = a:getSort()

but it is more efficient (speed, memory) to use a defined function than an anonymous one:

MyClass = class()
function MyClass.sort(a,b)
   return a<b 

a = MyClass()

f = a.sort

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

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.