Есть ли программа, которая может сортировать значения вывода программы Lua?

Мне нужна программа (для Windows), которая может сортировать в алфавитном порядке значения Lua в файле, которые сохраняются после выполнения и закрытия программы Lua. Мне приходится постоянно объединять 2 таких файла, и каждый раз вручную сортировать их перед запуском программы сравнения очень неудобно. Если возможно, тот, который не нуждается в Lua для работы.

Структура файла такая:

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,   },
}

person Normal Uzer    schedule 09.05.2011    source источник
comment
Lua, а не LUA. См. lua.org/about.html#name.   -  person lhf    schedule 09.05.2011
comment
Решение Lua было бы намного проще. Просто загрузите два файла и объедините или сравните таблицы.   -  person lhf    schedule 09.05.2011
comment
Определите, что вы подразумеваете под сортировкой   -  person David Heffernan    schedule 09.05.2011
comment
Если вы хотите написать инструмент, добро пожаловать в stackoverflow. Если вы ищете существующие инструменты, проверьте superuser.com   -  person karlphillip    schedule 10.05.2011
comment
Пожалуйста, включите желаемый результат, который вы хотите. Тот, который вы делаете вручную сейчас. Вполне возможно, что код Lua, который выполняет слияние за вас, буквально меньше 10 строк.   -  person kikito    schedule 10.05.2011
comment
Желаемый вывод — тот, что в примере, фактические файлы такие же, но я могу получить Val50 в первой строке, Val5 во второй, Val13 в третьей и так далее (ValX может быть числом, словом или сочетание того и другого). Также иногда ValX может быть массивом значений...   -  person Normal Uzer    schedule 11.05.2011
comment
Ваш вывод не является допустимым вводом Lua - десятичные числа должны быть записаны с ., а не ,.   -  person Paŭlo Ebermann    schedule 11.05.2011


Ответы (1)


Измените свои программы на Lua, чтобы они выводили данные в отсортированном порядке.

Я не уверен, что вы используете для вывода этого, я предполагаю что-то вроде сериализации в разделе "Программирование на Lua" с добавленным отступом.

Вам нужно всего лишь изменить for k,v in pairs(o) do на for k,v in pairsByKeys(o) do с помощью функции pairsByKeys из главы 19.3. Вот полный пример, который выводит что-то вроде того, что вы там дали.

-- 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, "")

Если вы не можете изменить программы, вы можете загрузить ввод в Lua, а затем снова вывести их с помощью этого метода сериализации. Следующая программа делает это (используя описанный выше метод serialize_sorted):

-- 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

Это может создавать файлы, как в вашем вопросе, даже с отступом, но с правильными запятыми.

Эта сортировка не работает, если у вас есть некоторая таблица со строковыми и числовыми ключами - тогда вам придется подумать о том, как их отсортировать относительно, и передать функцию сравнения.

person Paŭlo Ebermann    schedule 11.05.2011