Skip to main content

01.Table转换为JSON的算法实现

1 为什么要自己实现这个算法

因为lua是一个轻量级的脚本语言,而轻量也意味着好多标准库或功能压根就没有,需要 开发者自己去实现,包括Json相关的转换的库,官方也没有,想要用,要么引用第三方开源, 要么自己去实现。

2 实现示例

utils/table.lua
local Table = {}

function Table:getInstance(obj)
obj = obj or {}
local data = obj
setmetatable(data, self)
self.__index = self

return data
end

-- Get Table size
function Table:getLength()
local size = 0
for _ in pairs(self) do size = size + 1 end
return size
end

-- Check the Data is Array.
function Table:isArray()
for key, _ in pairs(self) do
if (type(key) ~= 'number') then
return false
end
end

return true
end

return Table
utils/json.lua
local Table = require('utils.table')
local Module = { }

local function formatField(isArray, key, value)
if isArray then
return string.format("%s", value)
end
return string.format('"%s":%s', key, value)
end

-- Convert table data to string.
function Module.encode(data, level)
level = level or 0
local result = ''
local size = 0
local symbol = ''
local tableSize =Table:getInstance(data):getLength()
local isArray = Table:getInstance(data):isArray()
for index, value in pairs(data) do
size = size + 1
if (size < tableSize) then
symbol = ','
else
symbol = ''
end
local valueType = type(value)
if (valueType == 'table') then
result = result .. formatField(isArray, index, Module.encode(value, level + 1) .. symbol)
elseif valueType == 'boolean' then
local boolStr = 'true'
if not value then
boolStr = 'false'
end
result = result .. formatField(isArray, index, boolStr .. symbol)
elseif valueType == 'number' then
result = result .. formatField(isArray, index, string.format('%s', value) .. symbol)
else
result = result .. formatField(isArray, index, string.format('"%s"', value) .. symbol)
end
end
local leftSymbol = '{'
local rightSymbol = '}'
if isArray then
leftSymbol = '['
rightSymbol = ']'
end
return string.format("%s%s%s", leftSymbol, result, rightSymbol)
end

return Module

3 使用测试

local Json = require('utils.json')
local testTable = {
str = 'string',
number = {1, 2, 3, 4},
bool = true,
collectStr = {
foo = "foo value",
bar = "bar str"
},
collectNumber = {
foo = {1, 2, 3, {4, 5, 6}},
bar = {{7, 8, 9}, 10 }
},
collectBool = {
true,
false,
true
},
mix = {
"str",
10,
false,
table = {
1, 2, 3, 4, {'foo', 'bar'}, false,
},
}
}

print(Json.encode(testTable))
输出结果
{
"str": "string",
"number": [
1,
2,
3,
4
],
"bool": true,
"collectNumber": {
"bar": [
[
7,
8,
9
],
10
],
"foo": [
1,
2,
3,
[
4,
5,
6
]
]
},
"collectBool": [
true,
false,
true
],
"mix": {
"1": "str",
"2": 10,
"3": false,
"table": [
1,
2,
3,
4,
[
"foo",
"bar"
],
false
]
},
"collectStr": {
"bar": "bar str",
"foo": "foo value"
}
}