refactor(table): improve performance of contains, matches, and merge (#647)

This commit is contained in:
Guru Saran
2024-10-01 14:21:52 +05:30
committed by GitHub
parent f5d6cebfaa
commit 4c460e0bd9

View File

@@ -9,24 +9,30 @@ local pairs = pairs
---@return boolean ---@return boolean
---Checks if tbl contains the given values. Only intended for simple values and unnested tables. ---Checks if tbl contains the given values. Only intended for simple values and unnested tables.
local function contains(tbl, value) local function contains(tbl, value)
if not next(tbl) then return false end
if type(value) ~= 'table' then if type(value) ~= 'table' then
for _, v in pairs(tbl) do for _, v in pairs(tbl) do
if v == value then return true end if v == value then
return true
end end
else
local matched_values = 0
local values = 0
for _, v1 in pairs(value) do
values += 1
for _, v2 in pairs(tbl) do
if v1 == v2 then matched_values += 1 end
end
end
if matched_values == values then return true end
end end
return false return false
else
local set = {}
for _, v in pairs(tbl) do
set[v] = true
end
for _, v in pairs(value) do
if not set[v] then
return false
end
end
return true
end
end end
---@param t1 any ---@param t1 any
@@ -34,19 +40,24 @@ end
---@return boolean ---@return boolean
---Compares if two values are equal, iterating over tables and matching both keys and values. ---Compares if two values are equal, iterating over tables and matching both keys and values.
local function table_matches(t1, t2) local function table_matches(t1, t2)
local type1, type2 = type(t1), type(t2) local tabletype1 = table.type(t1)
if type1 ~= type2 then return false end if not tabletype1 then return t1 == t2 end
if type1 ~= 'table' and type2 ~= 'table' then return t1 == t2 end if tabletype1 ~= table.type(t2) or (tabletype1 == 'array' and #t1 ~= #t2) then
return false
for k1,v1 in pairs(t1) do
local v2 = t2[k1]
if v2 == nil or not table_matches(v1,v2) then return false end
end end
for k2,v2 in pairs(t2) do for k, v1 in pairs(t1) do
local v1 = t1[k2] local v2 = t2[k]
if v1 == nil or not table_matches(v1,v2) then return false end if v2 == nil or not table_matches(v1, v2) then
return false
end
end
for k in pairs(t2) do
if t1[k] == nil then
return false
end
end end
return true return true
@@ -74,17 +85,18 @@ end
---@return table ---@return table
---Merges two tables together. Defaults to adding duplicate keys together if they are numbers, otherwise they are overriden. ---Merges two tables together. Defaults to adding duplicate keys together if they are numbers, otherwise they are overriden.
local function table_merge(t1, t2, addDuplicateNumbers) local function table_merge(t1, t2, addDuplicateNumbers)
if addDuplicateNumbers == nil then addDuplicateNumbers = true end addDuplicateNumbers = addDuplicateNumbers ~= nil and addDuplicateNumbers or true
for k, v in pairs(t2) do for k, v2 in pairs(t2) do
local type1 = type(t1[k]) local v1 = t1[k]
local type2 = type(v) local type1 = type(v1)
local type2 = type(v2)
if type1 == 'table' and type2 == 'table' then if type1 == 'table' and type2 == 'table' then
table_merge(t1[k], v, addDuplicateNumbers) table_merge(v1, v2, addDuplicateNumbers)
elseif addDuplicateNumbers and (type1 == 'number' and type2 == 'number') then elseif addDuplicateNumbers and (type1 == 'number' and type2 == 'number') then
t1[k] += v t1[k] = v1 + v2
else else
t1[k] = v t1[k] = v2
end end
end end