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