Has run into the lua table library sort function not being completely reliable?
I have been sorting a list of id / tag pairs, and I wanted the sort to be first by id and then by tag, with the wrinkle that Name would always come first. It works fine except for an occasional few cases where the name did not come first. I debugged the sort function and could not spot it making any mistakes. I then knocked up a bubble sort and used that instead, and no mistakes.
The attached plugin takes one of my errant data sets and sorts it both ways, and you can see the third and fourth items are incorrect with table.sort and correct with the bubble. Counting the calls to the sort function shows up the inefficiency of the bubble - but accuracy is the first priority!
* table.sort
table.sort
Last edited by Barnowl on 16 Sep 2015 00:54, edited 1 time in total.
Ian Johnson - researching Bain, Batley, Elsden, Ewen and Johnson families and the village of Easton Royal
(i>
(i>
Re: table.sort
Sorry missed the attachment 
- Attachments
-
sorttest.fh_lua- (2.13 KiB) Downloaded 167 times
Ian Johnson - researching Bain, Batley, Elsden, Ewen and Johnson families and the village of Easton Royal
(i>
(i>
- tatewise
- Megastar
- Posts: 27082
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: table.sort
BTW: You could have added the Attachment by using the left most Edit post icon on your original posting.
Yes, it is a bit mysterious, but debugging the sortfunc with a break point where C1.id == 510 reveals that table.sort sometimes compares a table entry with itself.
e.g. C1 = { id=510, tag="NAME" } versus C2 = { id=510, tag="NAME" }
In this case the bRet value must be false, i.e. C1 is not less than C2.
So in the script after
if (C1.id == C2.id) then
insert
if (C1.tag == C2.tag) then
bRet = false
else
with a matching end and it works correctly!
(There may be a slightly more efficient solution.)
P.S.
I added the following two lines to your test data:
t[25] = { id=510, tag="CENS" }
t[26] = { id=510, tag="CENS" }
and with old sortfunc it even mis-sorts the id but the new code is OK and uses less comparisons.
Yes, it is a bit mysterious, but debugging the sortfunc with a break point where C1.id == 510 reveals that table.sort sometimes compares a table entry with itself.
e.g. C1 = { id=510, tag="NAME" } versus C2 = { id=510, tag="NAME" }
In this case the bRet value must be false, i.e. C1 is not less than C2.
So in the script after
if (C1.id == C2.id) then
insert
if (C1.tag == C2.tag) then
bRet = false
else
with a matching end and it works correctly!
(There may be a slightly more efficient solution.)
P.S.
I added the following two lines to your test data:
t[25] = { id=510, tag="CENS" }
t[26] = { id=510, tag="CENS" }
and with old sortfunc it even mis-sorts the id but the new code is OK and uses less comparisons.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
Re: table.sort
Thanks Mike. Just shows that you have to read the library reference with a magnifying glass!! I had spotted the comparisons of the record with itself, but assumed it wouldn't matter what was returned in that case - which is true for the bubble sort. But as you point out the manual does say return true if less.
Ian Johnson - researching Bain, Batley, Elsden, Ewen and Johnson families and the village of Easton Royal
(i>
(i>
- tatewise
- Megastar
- Posts: 27082
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: table.sort
A couple of tiny tips, that may not be relevant here, but may help later.
Instead of for n = 1, 24 do use for n = 1, #t1 do which automatically adapts to the size of a simple array table.
Instead of t[1] = { id=1398, tag="NAME" } et seq, use table.insert({ id=1398, tag="NAME" }) which automatically increments the index.
Instead of for n = 1, 24 do use for n = 1, #t1 do which automatically adapts to the size of a simple array table.
Instead of t[1] = { id=1398, tag="NAME" } et seq, use table.insert({ id=1398, tag="NAME" }) which automatically increments the index.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry