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 type(value) ~= 'table' then if not next(tbl) then return false end
for _, v in pairs(tbl) do
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 type(value) ~= 'table' then
if v1 == v2 then matched_values += 1 end for _, v in pairs(tbl) do
end if v == value then
end return true
if matched_values == values then return true end 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,22 +40,27 @@ 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
end
for k1,v1 in pairs(t1) do for k, v1 in pairs(t1) do
local v2 = t2[k1] local v2 = t2[k]
if v2 == nil or not table_matches(v1,v2) then return false end if v2 == nil or not table_matches(v1, v2) then
end return false
end
end
for k2,v2 in pairs(t2) do for k in pairs(t2) do
local v1 = t1[k2] if t1[k] == nil then
if v1 == nil or not table_matches(v1,v2) then return false end return false
end end
end
return true return true
end end
---@generic T ---@generic T
@@ -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