问题
I need a program (for windows) that can sort alphabetically the Lua values in the file there are saved after the Lua program is executed and closed. I have to merge 2 such files constantly and it's a pain to sort them manually each time before running the comparison software. If possible one that doesn't need Lua in order to work.
The file structure is like:
SavedVars = {
["1"] = {
["Val1"] = true,
["Val2"] = true,
["Val3"] = false,
...
["ValX"] = true,
},
["2"] = {
["Val1"] = true,
["Val2"] = true,
["Val3"] = false,
...
["ValX"] = true, },
["X"] = {
["Val1"] = true,
["Val2"] = true,
["Val3"] = false,
...
["ValX"] = true, },
}
SavedStats = {
["1"] = {
["Val1"] = 0,
["Val2"] = 1,
["Val3"] = 55,
...
["ValX"] = -55,
},
["2"] = {
["Val1"] = 0,0005,
["Val2"] = -0,0000000007648,
["Val3"] = 4,
...
["ValX"] = true, },
["X"] = {
["Val1"] = 0,
["Val2"] = 0,
["Val3"] = 0,
...
["ValX"] = 0, },
}
回答1:
Change your Lua programs to output the stuff in sorted order.
I'm not sure what you are using to output this, I'm assuming something like the serialization function in "Programming in Lua", with added indentation.
You only have to change the for k,v in pairs(o) do
to for k,v in pairsByKeys(o) do
, with the pairsByKeys
function from chapter 19.3. Here is a complete example which outputs something like you gave there.
-- serializes some object to the standard output.
--
-- o - the object to be formatted.
-- indent - a string used for indentation for tables.
-- cmp - a comparison function to sort the subtables.
-- May be nil, then we sort alphabetically (strings)
-- or numerically (numbers).
--
-- from http://www.lua.org/pil/12.1.1.html, modified to include
-- indentation and sorting.
--
function serialize_sorted (o, indent, cmp)
if type(o) == "nil" then
-- this should not really happen on recursion, as nil can
-- be neither key nor value in a table.
io.write("nil")
elseif type(o) == "number" then
io.write(o)
elseif type(o) == "string" then
io.write(string.format("%q", o))
elseif type(o) == "boolean" then
io.write( tostring(o) )
elseif type(o) == "table" then
io.write("{\n")
local subindent = indent .. " "
for k,v in pairsByKeys(o) do
io.write(subindent)
io.write("[")
serialize_sorted(k, subindent, cmp)
io.write("] = ")
serialize_sorted(v, subindent, cmp)
io.write(",\n")
end
io.write(indent .. "}")
else
error("cannot serialize a " .. type(o))
end
end
-- iterates over a table by key order.
--
-- t - the table to iterate over.
-- f - a comparator function used to sort the keys.
-- It may be nil, then we use the default order
-- for strings or numbers.
--
-- from http://www.lua.org/pil/19.3.html
--
function pairsByKeys (t, f)
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0 -- iterator counter
local iter = function () -- iterator function
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]]
end
end
return iter
end
-- our unsorted test table
testTable = {
["2"] = {
["Val1"] = true,
["ValX"] = true,
["Val2"] = true,
["Val3"] = false,
},
["1"] = {
["ValX"] = true,
["Val1"] = true,
["Val2"] = true,
["Val3"] = false,
},
["X"] = {
["Val3"] = false,
["ValX"] = true,
["Val1"] = true,
["Val2"] = true,
},
}
-- the output.
io.write("SavedVars = ")
serialize_sorted(testTable, "")
If you can't change the programs, you could load the input in Lua and then output them again with this serialization method. The following program does this (using the serialize_sorted method above):
-- loads a string to a table.
-- this executes the string with the
-- environment of a new table, and then
-- returns the table.
--
-- The code in the string should not need
-- any variables it does not declare itself,
-- as these are not available on runtime.
-- It runs in a really empty environment.
function loadTable(data)
local table = {}
local f = assert(loadstring(data))
setfenv(f, table)
f()
return table
end
-- read input from stdin
local data = io.read("*all")
-- load table
local testTable = loadTable(data)
-- output everything
for k, v in pairsByKeys(testTable) do
io.write(k .. " = ")
serialize_sorted(v, "")
io.write("\n")
end
This can create files like in your question, even with indentation, but with right commas.
This sorting does not work if you have some table with both string and number keys - then you would have to think about how to sort them relatively, and pass a comparator function.
来源:https://stackoverflow.com/questions/5940117/is-there-an-program-that-can-sort-the-values-of-a-lua-program-output