Modified the sort function signature to also pass the original table, so not only keys are available when sorting, but also the values in the original table.

This commit is contained in:
Thijs Schreijer 2013-02-27 22:31:18 +01:00
parent 16c5599903
commit fff87fea74
2 changed files with 32 additions and 12 deletions

View File

@ -51,13 +51,13 @@ internal function, but set different options by default:
* name (string) -- name; triggers full serialization with self-ref section * name (string) -- name; triggers full serialization with self-ref section
* indent (string) -- indentation; triggers long multi-line output * indent (string) -- indentation; triggers long multi-line output
* comment (true/False/maxlevel) -- provide stringified value in a comment (up to maxlevel of depth) * comment (true/false/maxlevel) -- provide stringified value in a comment (up to maxlevel of depth)
* sortkeys (true/False) -- sort keys * sortkeys (true/false/function) -- sort keys
* sparse (true/False) -- force sparse encoding (no nil filling based on #t) * sparse (true/false) -- force sparse encoding (no nil filling based on #t)
* compact (true/False) -- remove spaces * compact (true/false) -- remove spaces
* fatal (true/False) -- raise fatal error on non-serilizable values * fatal (true/false) -- raise fatal error on non-serilizable values
* nocode (true/False) -- disable bytecode serialization for easy comparison * nocode (true/false) -- disable bytecode serialization for easy comparison
* nohuge (true/False) -- disable checking numbers against undefined and huge values * nohuge (true/false) -- disable checking numbers against undefined and huge values
* maxlevel (number) -- specify max level up to which to expand nested tables * maxlevel (number) -- specify max level up to which to expand nested tables
* valignore (table) -- allows to specify a list of values to ignore (as keys) * valignore (table) -- allows to specify a list of values to ignore (as keys)
* keyallow (table) -- allows to specify the list of keys to be serialized. Any keys not in this list are not included in final output (as keys) * keyallow (table) -- allows to specify the list of keys to be serialized. Any keys not in this list are not included in final output (as keys)
@ -72,6 +72,26 @@ line(a, {nocode = true, valignore = {[arrayToIgnore] = true}})
function todiff(a) return dump(a, {nocode = true, indent = ' '}) end function todiff(a) return dump(a, {nocode = true, indent = ' '}) end
``` ```
## Sorting
A custom sort function can be provided to sort the contents of tables. The function takes 2 parameters, the first being the table (a list) with the keys, the second the original table. It should modify the first table in-place, and return nothing.
For example, the following call will apply a sort function identical to the standard sort, except that it will not distinguish between lower- and uppercase.
```lua
local mysort = function(k, o) -- k=keys, o=original table
local maxn, to = 12, {number = 'a', string = 'b'}
local function padnum(d) return ("%0"..maxn.."d"):format(d) end
local sort = function(a,b)
return ((k[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))):upper()
< ((k[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum))):upper()
end
table.sort(k, sort)
end
local content = { some = 1, input = 2, to = 3, serialize = 4 }
local result = require('serpent').block(content, {sortkeys = mysort})
```
## Formatters ## Formatters
Serpent supports a way to provide a custom formatter that allows to fully Serpent supports a way to provide a custom formatter that allows to fully

View File

@ -29,12 +29,12 @@ local function s(t, opts)
local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n] local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
local safe = plain and n or '['..safestr(n)..']' local safe = plain and n or '['..safestr(n)..']'
return (path or '')..(plain and path and '.' or '')..safe, safe end return (path or '')..(plain and path and '.' or '')..safe, safe end
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(o, n) local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'} local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
local function padnum(d) return ("%0"..maxn.."d"):format(d) end local function padnum(d) return ("%0"..maxn.."d"):format(d) end
table.sort(o, function(a,b) table.sort(k, function(a,b)
return (o[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum)) return (k[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
< (o[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end < (k[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
local function val2str(t, name, indent, insref, path, plainindex, level) local function val2str(t, name, indent, insref, path, plainindex, level)
local ttype, level = type(t), (level or 0) local ttype, level = type(t), (level or 0)
local spath, sname = safename(path, name) local spath, sname = safename(path, name)
@ -63,7 +63,7 @@ local function s(t, opts)
local maxn, o, out = #t, {}, {} local maxn, o, out = #t, {}, {}
for key = 1, maxn do table.insert(o, key) end for key = 1, maxn do table.insert(o, key) end
for key in pairs(t) do if not o[key] then table.insert(o, key) end end for key in pairs(t) do if not o[key] then table.insert(o, key) end end
if opts.sortkeys then alphanumsort(o, opts.sortkeys) end if opts.sortkeys then alphanumsort(o, t, opts.sortkeys) end
for n, key in ipairs(o) do for n, key in ipairs(o) do
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing