9

I'm currently have a larger program in LuaTeX (which is a TeX engine with a builtin lua interpreter) and in one part of the program a table is sorted. The table elements are itself tables with a certain structure and the sorting function looks like this:

function sort_list_function (a,b)

  if a.totalfilll < b.totalfilll then
    return true
  elseif a.totalfill < b.totalfill then
    return true
  elseif a.totalfil < b.totalfil then
    return true
  elseif a.totalvalue + a.height + a.totalplus <
         b.totalvalue + b.height + b.totalplus
  then   
    return true
  else
    return false
  end       
end

All element values are numbers, so from my understanding the requirement for the comparison function are fulfilled, but perhaps my thinking is off here (which is basically the question, i.e., why or under what circumstances could the above result in an invalid order function error).

The error is unfortunately only very diffcult to isolate and happened only in once case and then only after the codes has done very many sorts successfully, so as a first step I want to make sure that I'm not totally missing something clearly wrong with a function like the above.

3
  • 2
    Hint: Consider the results of both sort_list_function(a,b) and sort_list_function(b,a) for a = {totalfilll = 1, totalfill = 2}; b = {totalfilll = 2, totalfill = 1}; Commented May 7, 2016 at 19:18
  • @ColonelThirtyTwo thanks, so may fear was right, need my marbles polished, so there is the way to get both directions true in a simple example, I just didn't see Commented May 7, 2016 at 19:58
  • Note: if a > b is true, a <= b must be false, that is, if given a,b=true, it must be that b,a=false Commented Dec 5, 2023 at 2:57

2 Answers 2

8

ok, thanks to the hint from @ColonelThirtyTwo, the answer is that the comparison function is indeed wrong and I have to explicitly handle the > cases as well and immediately return false (as in my case the different tests are meant to be of different order of importance) e.g., something like

  if a.totalfilll < b.totalfilll then
    return true
  elseif a.totalfilll > b.totalfilll then
    return false
  elseif a.totalfill < b.totalfill then
    return true
  elseif a.totalfill > b.totalfill then
    return false
  elseif a.totalfil < b.totalfil then
    return true
  elseif a.totalfil > b.totalfil then
    return false
  else
    return ( a.totalvalue + a.height + a.totalplus <
             b.totalvalue + b.height + b.totalplus    )
  end   
Sign up to request clarification or add additional context in comments.

Comments

1

An alternative method of comparison that I find easy to understand.

function sort_list_function (a,b)
  if a.totalfilll ~= b.totalfilll then
    return a.totalfilll < b.totalfilll
  elseif a.totalfill ~= b.totalfill then
    return a.totalfill < b.totalfill
  elseif a.totalfil ~= b.totalfil then
    return a.totalfil < b.totalfil
  else
    return ( a.totalvalue + a.height + a.totalplus <
             b.totalvalue + b.height + b.totalplus )
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.