Lua add key value pair into table (array) - lua

In my Lua project I receive an array, encode it into JSON and pass further. My Lua encode function looks like the following:
local function encode_table(val, stack)
local res = {}
stack = stack or {}
-- Circular reference?
if stack[val] then error("circular reference") end
stack[val] = true
if val[1] ~= nil or next(val) == nil then
-- Treat as array -- check keys are valid and it is not sparse
local n = 0
for k in pairs(val) do
if type(k) ~= "number" then
error("invalid table: mixed or invalid key types")
end
n = n + 1
end
-- need to add a stub somewhere here above the next line
if n ~= #val then
error("invalid table: sparse array") -- THIS TRIGGERS and stops the code
end
-- Encode
for i, v in ipairs(val) do
table.insert(res, encode(v, stack))
end
stack[val] = nil
return "[" .. table.concat(res, ",") .. "]"
else
-- Treat as an object
for k, v in pairs(val) do
if type(k) ~= "string" then
error("invalid table: mixed or invalid key types")
end
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
end
stack[val] = nil
return "{" .. table.concat(res, ",") .. "}"
end
end
The problem is that I reveive an array with a 1 element missing. I need to add a stub for it in a key - value manner, say
myArray['missingKey'] = 'somestubvalue'
but I donk know how to do that. Also there is a check in the code for sparse array and this check throws an error, so I need to add a stub before this check is done (pls see the code). Any ideas how to do that would be welcome. Thank you.

Related

LUA, Unpack all the hierarchy of a Nested Table and store and return Table with all the elements at the same hierarchy

I have a nested array, for example,
someTable = {"value1", "value2", {"value3a", "value3b", {"value4a", "value4b", "value4c"}}
and trying to find a way to get all of these different elements at different hierarchies to actually come down to a single hierarchy
expected results,
newTable = {"value1", "value2", "value3a", "value3b", "value4a", "value4b", "value4c"}
I've found this below code that actually prints all those elements, but I couldn't find a way to make it into a new table with one hierarchy an return it
function DeepPrint (e)
-- if e is a table, we should iterate over its elements
if type(e) == "table" then
for k,v in pairs(e) do -- for every element in the table
print(k)
DeepPrint(v) -- recursively repeat the same procedure
end
else -- if not, we can just print it
print(e)
end
end
I agree with what Doj is saying, but you don't need two functions to do that.
Just recursively call initial function, like you did with your print example above.
#! /usr/bin/env lua
someTable = {"value1", "value2", {"value3a", "value3b", {"value4a", "value4b", "value4c"}}}
function flatten( item, result )
local result = result or {} -- create empty table, if none given during initialization
if type( item ) == 'table' then
for k, v in pairs( item ) do
flatten( v, result )
end
else
result[ #result +1 ] = item
end
return result
end
newTable = flatten( someTable )
for i = 1, #newTable do print( newTable[i] ) end
Instead of printing the elements just insert them to result table:
function flattenRecursive(e, result)
-- if e is a table, we should iterate over its elements
if type(e) == "table" then
for k,v in pairs(e) do -- for every element in the table
flattenRecursive(v, result) -- recursively repeat the same procedure
end
else -- if not, we can just put it to the result
table.insert(result, e)
end
end
function flatten (e)
local result = {}
flattenRecursive(e, result)
return result
end
Test:
example = {"value1", "value2", {"value3a", "value3b", {"value4a", "value4b", "value4c"}}}
example_result = flatten(example)
for k,v in pairs(example_result) do
print(v)
end

Bubble Sort algorithm in Lua will not work

I am currently learning Lua, and I am attempting to create a bubble sort algorithm with it. However, I am unable to get this to work. Is anyone able to point out why?
Some details I can point out are that, on shorter lists such as lists 3 elements long, the algorithm does succeed in sorting it but then continues to sort it as if it was not sorted. On longer lists such as lists 5 elements long, the program does not sort it at all. I have gotten this information by making the program print the list every time two elements are swapped.
user_input = 0
list = {}
while user_input ~= "SORT" do
print("Input number value, or input SORT to start sort")
user_input = io.read()
if user_input ~= "SORT" then
table.insert(list, user_input)
end
end
done = false
while done == false do
done = true
for k, v in pairs(list) do
if k ~= 1 then
if list[k] < list[k - 1] then
list[k], list[k - 1] = list[k - 1], list[k]
done = false
for k, v in pairs(list) do
io.write(v .. " ")
end
print()
end
end
if k == 1 then
if list[k] < list[table.maxn(list)] then
list[k], list[table.maxn(list)] = list[table.maxn(list)], list[k]
done = false
for k, v in pairs(list) do
io.write(v .. " ")
end
print()
end
end
end
end
io.write("RESULT: ")
for k, v in pairs(list) do
io.write(v .. " ")
end
print()
In Lua there are 2 functions for creating iterators for tables pairs and ipairs
With pairs the order produced is indeterminate, it will returned all key, value pairs but the order can not be garenteed.
You can find this under next in the reference manual for Lua 5.1
example: {1,2,3,4,5} the output could be 5,2,4,1,3
the order of ipairs is 1 to the first nil it will not return any non-integer keys.
example: {1,2,3,nil,5} would give you 1,2,3
Using pairs your algorithm's output could be correct but could appear incorrect due to the ordering from pairs
You want you use ipairs to evaluate your algorithm's output, so that it will be ordered by index.
Your algorithm does not perform a bubble sort as it is now, I can include corrections for that if you want. For this initial answer I think clearing up what would create an inconsistent output should point you in the right direction.
A bubble sort should "sort" 1 index at a time, the first pass will get the last value of the array sorted. then each pass after sorts following position. for example:
before first pass 2,1,3,4,5,8,7,6
after first pass 1,2,3,4,5,7,6,8
Wikipedia has great pages for sorting algorithms with gif images that can really help understand how it should function: Bubble Sort
You're using pairs() instead of ipairs()
plus your code has an extra maxn() routine that isn't needed.
#! /usr/bin/env lua
local user_input = 0
local list = {}
while user_input ~= 'sort' do
print( 'Input number value, or input SORT to start sort' )
user_input = io.read() :lower()
-- the word 'sort' doesn't return a number, thus no final insertion
table.insert( list, tonumber( user_input ) )
end
local found_swap = true
while found_swap do
found_swap = false
for i = 2, #list do
if list[i] < list[i -1] then
list[i], list[i -1] = list[i -1], list[i]
found_swap = true
end
end
end
io.write( 'RESULT: ' )
for i, v in ipairs( list ) do
io.write( v ..' ' )
end
print()
here's my implementation, a couple notes:
My version of lua (luau) supports type checking etc. so you may need to remove : table from the paramater. (If you'd like to find more out about luau - here's the link: https://roblox.github.io/luau/ - it's really cool)
local function bubbleSort(t: table)
local function check(i, v)
local nextNum = t[i+1]
if nextNum and (nextNum < v) then
t[i] = nextNum
t[i + 1] = v
return true
end
end
local changeMade
repeat
changeMade = false
for i, v in next, t do
changeMade = check(i, v) or changeMade
end
until changeMade == false
end
local tableForSorting = {2,5,4} --2,4,5
bubbleSort(tableForSorting)
print(tableForSorting)
Hope this is of some help and shows how you can really slim down your codebase and it still work exactly the same! The reason yours wasn't working - as others - have mentioned is pairs() doesn't consistently order the list the same way.
In practise we use pairs() for dictionaries while we use ipairs() for arrays. You'll notice i'm using next in this example, next is exactly the same as ipairs(). Drop a question below if you have any follow up questions :)!

Error In Lua - Loop on map/list

I wrote the following function: deleteStrings .
That gets as input map of words and their length (mapWords),
and list of words.(listWords)
I want to remove from the map, keys that don't exist in the list.
I'm getting "lua error".
function deleteStrings(mapWords,listWords)
local CleanedMap = mapWords
for key in map.keys(mapWords) do
if not contains(listWords,key) then
CleanedMap=map.remove(CleanedMap,key)
end
end
end
function contains(list, word)
for _, v in pairs(list) do
if v == word then return true end
end
return false
end
What is wrong with this code?
Thanks

time complexity of metatable in Lua when accessing

local cls = {base = "base"}
local ins = {}
cls.__index = cls
setmetatable(ins, cls)
What is the time complexity of accesssing ins.base?
You can expect O(1) time complexity from the official Lua implementation.
The code for __index is roughly equivalent to this Lua code, taken from the manual:
function gettable_event (table, key)
local h
if type(table) == "table" then
local v = rawget(table, key)
if v ~= nil then return v end
h = metatable(table).__index
if h == nil then return nil end
else
h = metatable(table).__index
if h == nil then
error(ยทยทยท)
end
end
if type(h) == "function" then
return (h(table, key)) -- call the handler
else return h[key] -- or repeat operation on it
end
end
The __index lookup itself has no loops, and since Lua tables are backed by hash tables, table lookups are usually a constant-time operation.

get nested table result in lua

I have a table A that contain the following
for i,v in pairs(Table A) do print (i,v) end
1 a
2 table : 50382A03 -- table B
3 hi
. Is there a way that I can get the table B value to be print out while I m printing the parent table A, or i can store it and print it again using the same function?.
thanks
Jp
When the question contains "nested", the answer will probably contain recursion:
function printTable(t)
function printTableHelper(t, spacing)
for k,v in pairs(t) do
print(spacing..tostring(k), v)
if (type(v) == "table") then
printTableHelper(v, spacing.."\t")
end
end
end
printTableHelper(t, "");
end
Just beware of circular references.
A bit changed function for better output and abstraction:
function printTableHelper(t,spacing)
local spacing = spacing or ''
if type(t)~='table' then
print(spacing..tostring(t))
else
for k,v in pairs(t) do
print(spacing..tostring(k),v)
if type(v)=='table' then
printTableHelper(v,spacing..'\t')
end
end
end
end
printTableHelper({'a',{'b'},'c'})
Just head on to the lua-users wiki page on table serialization and choose your champion. For example the following code handles everything including cycles in tables (local a={}; a.t = a):
-- alt version2, handles cycles, functions, booleans, etc
-- - abuse to http://richard.warburton.it
-- output almost identical to print(table.show(t)) below.
function print_r (t, name, indent)
local tableList = {}
function table_r (t, name, indent, full)
local serial=string.len(full) == 0 and name
or type(name)~="number" and '["'..tostring(name)..'"]' or '['..name..']'
io.write(indent,serial,' = ')
if type(t) == "table" then
if tableList[t] ~= nil then io.write('{}; -- ',tableList[t],' (self reference)\n')
else
tableList[t]=full..serial
if next(t) then -- Table not empty
io.write('{\n')
for key,value in pairs(t) do table_r(value,key,indent..'\t',full..serial) end
io.write(indent,'};\n')
else io.write('{};\n') end
end
else io.write(type(t)~="number" and type(t)~="boolean" and '"'..tostring(t)..'"'
or tostring(t),';\n') end
end
table_r(t,name or '__unnamed__',indent or '','')
end

Resources