fix table module
This commit is contained in:
parent
e05369431c
commit
52fe63df39
@ -3,6 +3,7 @@ local orig_remove = table.remove
|
||||
local orig_concat = table.concat
|
||||
local orig_sort = table.sort
|
||||
|
||||
-- Enhanced table.insert with validation
|
||||
function table.insert(t, pos, value)
|
||||
if type(t) ~= "table" then error("table.insert: first argument must be a table", 2) end
|
||||
|
||||
@ -18,6 +19,7 @@ function table.insert(t, pos, value)
|
||||
end
|
||||
end
|
||||
|
||||
-- Enhanced table.remove with validation
|
||||
function table.remove(t, pos)
|
||||
if type(t) ~= "table" then error("table.remove: first argument must be a table", 2) end
|
||||
if pos ~= nil and (type(pos) ~= "number" or pos ~= math.floor(pos)) then
|
||||
@ -26,6 +28,7 @@ function table.remove(t, pos)
|
||||
return orig_remove(t, pos)
|
||||
end
|
||||
|
||||
-- Enhanced table.concat with validation
|
||||
function table.concat(t, sep, start_idx, end_idx)
|
||||
if type(t) ~= "table" then error("table.concat: first argument must be a table", 2) end
|
||||
if sep ~= nil and type(sep) ~= "string" then error("table.concat: separator must be a string", 2) end
|
||||
@ -38,17 +41,24 @@ function table.concat(t, sep, start_idx, end_idx)
|
||||
return orig_concat(t, sep, start_idx, end_idx)
|
||||
end
|
||||
|
||||
-- Enhanced table.sort with validation
|
||||
function table.sort(t, comp)
|
||||
if type(t) ~= "table" then error("table.sort: first argument must be a table", 2) end
|
||||
if comp ~= nil and type(comp) ~= "function" then error("table.sort: comparator must be a function", 2) end
|
||||
orig_sort(t, comp)
|
||||
end
|
||||
|
||||
--- Returns the length of an array-like table
|
||||
-- @param t table to measure
|
||||
-- @return number of array elements
|
||||
function table.length(t)
|
||||
if type(t) ~= "table" then error("table.length: argument must be a table", 2) end
|
||||
return #t
|
||||
end
|
||||
|
||||
--- Returns the total number of key-value pairs in a table
|
||||
-- @param t table to count
|
||||
-- @return total number of elements
|
||||
function table.size(t)
|
||||
if type(t) ~= "table" then error("table.size: argument must be a table", 2) end
|
||||
local count = 0
|
||||
@ -58,11 +68,17 @@ function table.size(t)
|
||||
return count
|
||||
end
|
||||
|
||||
--- Checks if a table is empty
|
||||
-- @param t table to check
|
||||
-- @return true if table has no elements
|
||||
function table.is_empty(t)
|
||||
if type(t) ~= "table" then error("table.is_empty: argument must be a table", 2) end
|
||||
return next(t) == nil
|
||||
end
|
||||
|
||||
--- Checks if a table is an array (contiguous integer keys starting from 1)
|
||||
-- @param t table to check
|
||||
-- @return true if table is an array
|
||||
function table.is_array(t)
|
||||
if type(t) ~= "table" then error("table.is_array: argument must be a table", 2) end
|
||||
if table.is_empty(t) then return true end
|
||||
@ -79,6 +95,8 @@ function table.is_array(t)
|
||||
return max_index == count
|
||||
end
|
||||
|
||||
--- Removes all elements from a table
|
||||
-- @param t table to clear
|
||||
function table.clear(t)
|
||||
if type(t) ~= "table" then error("table.clear: argument must be a table", 2) end
|
||||
for k in pairs(t) do
|
||||
@ -86,6 +104,9 @@ function table.clear(t)
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a shallow copy of a table
|
||||
-- @param t table to clone
|
||||
-- @return new table with same key-value pairs
|
||||
function table.clone(t)
|
||||
if type(t) ~= "table" then error("table.clone: argument must be a table", 2) end
|
||||
local result = {}
|
||||
@ -95,6 +116,9 @@ function table.clone(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Creates a deep copy of a table, handling circular references
|
||||
-- @param t table to deep copy
|
||||
-- @return new table with recursively copied values
|
||||
function table.deep_copy(t)
|
||||
if type(t) ~= "table" then error("table.deep_copy: argument must be a table", 2) end
|
||||
|
||||
@ -115,6 +139,10 @@ function table.deep_copy(t)
|
||||
return copy_recursive(t, {})
|
||||
end
|
||||
|
||||
--- Checks if a table contains a specific value
|
||||
-- @param t table to search
|
||||
-- @param value value to find
|
||||
-- @return true if value is found
|
||||
function table.contains(t, value)
|
||||
if type(t) ~= "table" then error("table.contains: first argument must be a table", 2) end
|
||||
for _, v in pairs(t) do
|
||||
@ -123,6 +151,10 @@ function table.contains(t, value)
|
||||
return false
|
||||
end
|
||||
|
||||
--- Returns the first key that maps to the given value
|
||||
-- @param t table to search
|
||||
-- @param value value to find
|
||||
-- @return key that maps to value, or nil if not found
|
||||
function table.index_of(t, value)
|
||||
if type(t) ~= "table" then error("table.index_of: first argument must be a table", 2) end
|
||||
for k, v in pairs(t) do
|
||||
@ -131,6 +163,10 @@ function table.index_of(t, value)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Finds the first element that satisfies a predicate
|
||||
-- @param t table to search
|
||||
-- @param predicate function(value, key, table) -> boolean
|
||||
-- @return value, key of first matching element, or nil
|
||||
function table.find(t, predicate)
|
||||
if type(t) ~= "table" then error("table.find: first argument must be a table", 2) end
|
||||
if type(predicate) ~= "function" then error("table.find: second argument must be a function", 2) end
|
||||
@ -141,6 +177,10 @@ function table.find(t, predicate)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Finds the key of the first element that satisfies a predicate
|
||||
-- @param t table to search
|
||||
-- @param predicate function(value, key, table) -> boolean
|
||||
-- @return key of first matching element, or nil
|
||||
function table.find_index(t, predicate)
|
||||
if type(t) ~= "table" then error("table.find_index: first argument must be a table", 2) end
|
||||
if type(predicate) ~= "function" then error("table.find_index: second argument must be a function", 2) end
|
||||
@ -151,6 +191,10 @@ function table.find_index(t, predicate)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Counts elements matching a value or predicate
|
||||
-- @param t table to search
|
||||
-- @param value_or_predicate value to match or function(value, key, table) -> boolean
|
||||
-- @return number of matching elements
|
||||
function table.count(t, value_or_predicate)
|
||||
if type(t) ~= "table" then error("table.count: first argument must be a table", 2) end
|
||||
|
||||
@ -167,6 +211,10 @@ function table.count(t, value_or_predicate)
|
||||
return count
|
||||
end
|
||||
|
||||
--- Filters elements that satisfy a predicate
|
||||
-- @param t table to filter
|
||||
-- @param predicate function(value, key, table) -> boolean
|
||||
-- @return new table with elements that pass the test
|
||||
function table.filter(t, predicate)
|
||||
if type(t) ~= "table" then error("table.filter: first argument must be a table", 2) end
|
||||
if type(predicate) ~= "function" then error("table.filter: second argument must be a function", 2) end
|
||||
@ -195,6 +243,10 @@ function table.filter(t, predicate)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Filters elements that don't satisfy a predicate
|
||||
-- @param t table to filter
|
||||
-- @param predicate function(value, key, table) -> boolean
|
||||
-- @return new table with elements that fail the test
|
||||
function table.reject(t, predicate)
|
||||
if type(t) ~= "table" then error("table.reject: first argument must be a table", 2) end
|
||||
if type(predicate) ~= "function" then error("table.reject: second argument must be a function", 2) end
|
||||
@ -202,6 +254,10 @@ function table.reject(t, predicate)
|
||||
return table.filter(t, function(v, k, tbl) return not predicate(v, k, tbl) end)
|
||||
end
|
||||
|
||||
--- Transforms each element using a function
|
||||
-- @param t table to transform
|
||||
-- @param transformer function(value, key, table) -> new_value
|
||||
-- @return new table with transformed elements
|
||||
function table.map(t, transformer)
|
||||
if type(t) ~= "table" then error("table.map: first argument must be a table", 2) end
|
||||
if type(transformer) ~= "function" then error("table.map: second argument must be a function", 2) end
|
||||
@ -213,6 +269,10 @@ function table.map(t, transformer)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Transforms values while preserving keys
|
||||
-- @param t table to transform
|
||||
-- @param transformer function(value, key, table) -> new_value
|
||||
-- @return new table with transformed values
|
||||
function table.map_values(t, transformer)
|
||||
if type(t) ~= "table" then error("table.map_values: first argument must be a table", 2) end
|
||||
if type(transformer) ~= "function" then error("table.map_values: second argument must be a function", 2) end
|
||||
@ -224,6 +284,10 @@ function table.map_values(t, transformer)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Transforms keys while preserving values
|
||||
-- @param t table to transform
|
||||
-- @param transformer function(key, value, table) -> new_key
|
||||
-- @return new table with transformed keys
|
||||
function table.map_keys(t, transformer)
|
||||
if type(t) ~= "table" then error("table.map_keys: first argument must be a table", 2) end
|
||||
if type(transformer) ~= "function" then error("table.map_keys: second argument must be a function", 2) end
|
||||
@ -236,6 +300,11 @@ function table.map_keys(t, transformer)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Reduces table to a single value using an accumulator function
|
||||
-- @param t table to reduce
|
||||
-- @param reducer function(accumulator, value, key, table) -> new_accumulator
|
||||
-- @param initial optional initial accumulator value
|
||||
-- @return final accumulator value
|
||||
function table.reduce(t, reducer, initial)
|
||||
if type(t) ~= "table" then error("table.reduce: first argument must be a table", 2) end
|
||||
if type(reducer) ~= "function" then error("table.reduce: second argument must be a function", 2) end
|
||||
@ -259,6 +328,9 @@ function table.reduce(t, reducer, initial)
|
||||
return accumulator
|
||||
end
|
||||
|
||||
--- Sums all numeric values in a table
|
||||
-- @param t table containing numbers
|
||||
-- @return sum of all values
|
||||
function table.sum(t)
|
||||
if type(t) ~= "table" then error("table.sum: argument must be a table", 2) end
|
||||
local total = 0
|
||||
@ -269,6 +341,9 @@ function table.sum(t)
|
||||
return total
|
||||
end
|
||||
|
||||
--- Multiplies all numeric values in a table
|
||||
-- @param t table containing numbers
|
||||
-- @return product of all values
|
||||
function table.product(t)
|
||||
if type(t) ~= "table" then error("table.product: argument must be a table", 2) end
|
||||
local result = 1
|
||||
@ -279,6 +354,9 @@ function table.product(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Finds the minimum numeric value in a table
|
||||
-- @param t table containing numbers
|
||||
-- @return minimum value
|
||||
function table.min(t)
|
||||
if type(t) ~= "table" then error("table.min: argument must be a table", 2) end
|
||||
if table.is_empty(t) then error("table.min: table is empty", 2) end
|
||||
@ -293,6 +371,9 @@ function table.min(t)
|
||||
return min_val
|
||||
end
|
||||
|
||||
--- Finds the maximum numeric value in a table
|
||||
-- @param t table containing numbers
|
||||
-- @return maximum value
|
||||
function table.max(t)
|
||||
if type(t) ~= "table" then error("table.max: argument must be a table", 2) end
|
||||
if table.is_empty(t) then error("table.max: table is empty", 2) end
|
||||
@ -307,12 +388,19 @@ function table.max(t)
|
||||
return max_val
|
||||
end
|
||||
|
||||
--- Calculates the average of all numeric values
|
||||
-- @param t table containing numbers
|
||||
-- @return average value
|
||||
function table.average(t)
|
||||
if type(t) ~= "table" then error("table.average: argument must be a table", 2) end
|
||||
if table.is_empty(t) then error("table.average: table is empty", 2) end
|
||||
return table.sum(t) / table.size(t)
|
||||
end
|
||||
|
||||
--- Tests if all elements satisfy a predicate or are truthy
|
||||
-- @param t table to test
|
||||
-- @param predicate optional function(value, key, table) -> boolean
|
||||
-- @return true if all elements pass the test
|
||||
function table.all(t, predicate)
|
||||
if type(t) ~= "table" then error("table.all: first argument must be a table", 2) end
|
||||
|
||||
@ -329,6 +417,10 @@ function table.all(t, predicate)
|
||||
return true
|
||||
end
|
||||
|
||||
--- Tests if any element satisfies a predicate or is truthy
|
||||
-- @param t table to test
|
||||
-- @param predicate optional function(value, key, table) -> boolean
|
||||
-- @return true if at least one element passes the test
|
||||
function table.any(t, predicate)
|
||||
if type(t) ~= "table" then error("table.any: first argument must be a table", 2) end
|
||||
|
||||
@ -345,11 +437,18 @@ function table.any(t, predicate)
|
||||
return false
|
||||
end
|
||||
|
||||
--- Tests if no element satisfies a predicate or is truthy
|
||||
-- @param t table to test
|
||||
-- @param predicate optional function(value, key, table) -> boolean
|
||||
-- @return true if no elements pass the test
|
||||
function table.none(t, predicate)
|
||||
if type(t) ~= "table" then error("table.none: first argument must be a table", 2) end
|
||||
return not table.any(t, predicate)
|
||||
end
|
||||
|
||||
--- Removes duplicate values from a table
|
||||
-- @param t table to deduplicate
|
||||
-- @return new table with unique values
|
||||
function table.unique(t)
|
||||
if type(t) ~= "table" then error("table.unique: argument must be a table", 2) end
|
||||
|
||||
@ -375,6 +474,10 @@ function table.unique(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Returns elements common to both tables
|
||||
-- @param t1 first table
|
||||
-- @param t2 second table
|
||||
-- @return new table with intersecting values
|
||||
function table.intersection(t1, t2)
|
||||
if type(t1) ~= "table" then error("table.intersection: first argument must be a table", 2) end
|
||||
if type(t2) ~= "table" then error("table.intersection: second argument must be a table", 2) end
|
||||
@ -402,6 +505,10 @@ function table.intersection(t1, t2)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Combines two tables, keeping all unique values
|
||||
-- @param t1 first table
|
||||
-- @param t2 second table
|
||||
-- @return new table with all unique values from both tables
|
||||
function table.union(t1, t2)
|
||||
if type(t1) ~= "table" then error("table.union: first argument must be a table", 2) end
|
||||
if type(t2) ~= "table" then error("table.union: second argument must be a table", 2) end
|
||||
@ -425,6 +532,10 @@ function table.union(t1, t2)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Returns elements in first table but not in second
|
||||
-- @param t1 first table
|
||||
-- @param t2 second table
|
||||
-- @return new table with values from t1 that are not in t2
|
||||
function table.difference(t1, t2)
|
||||
if type(t1) ~= "table" then error("table.difference: first argument must be a table", 2) end
|
||||
if type(t2) ~= "table" then error("table.difference: second argument must be a table", 2) end
|
||||
@ -437,6 +548,9 @@ function table.difference(t1, t2)
|
||||
return table.filter(t1, function(v) return not set2[v] end)
|
||||
end
|
||||
|
||||
--- Reverses the order of elements in an array
|
||||
-- @param t array to reverse
|
||||
-- @return new array with elements in reverse order
|
||||
function table.reverse(t)
|
||||
if type(t) ~= "table" then error("table.reverse: argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.reverse: argument must be an array", 2) end
|
||||
@ -449,6 +563,9 @@ function table.reverse(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Randomly shuffles elements in an array
|
||||
-- @param t array to shuffle
|
||||
-- @return new array with elements in random order
|
||||
function table.shuffle(t)
|
||||
if type(t) ~= "table" then error("table.shuffle: argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.shuffle: argument must be an array", 2) end
|
||||
@ -466,6 +583,10 @@ function table.shuffle(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Rotates array elements by a number of positions
|
||||
-- @param t array to rotate
|
||||
-- @param positions number of positions to rotate (positive = right, negative = left)
|
||||
-- @return new array with rotated elements
|
||||
function table.rotate(t, positions)
|
||||
if type(t) ~= "table" then error("table.rotate: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.rotate: first argument must be an array", 2) end
|
||||
@ -488,6 +609,11 @@ function table.rotate(t, positions)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Extracts a section of an array
|
||||
-- @param t array to slice
|
||||
-- @param start_idx starting index (inclusive)
|
||||
-- @param end_idx ending index (inclusive, optional)
|
||||
-- @return new array containing the slice
|
||||
function table.slice(t, start_idx, end_idx)
|
||||
if type(t) ~= "table" then error("table.slice: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.slice: first argument must be an array", 2) end
|
||||
@ -513,6 +639,12 @@ function table.slice(t, start_idx, end_idx)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Modifies an array by removing elements and/or adding new ones
|
||||
-- @param t array to modify
|
||||
-- @param start_idx starting index for modification
|
||||
-- @param delete_count number of elements to remove
|
||||
-- @param ... elements to insert at start_idx
|
||||
-- @return array of removed elements
|
||||
function table.splice(t, start_idx, delete_count, ...)
|
||||
if type(t) ~= "table" then error("table.splice: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.splice: first argument must be an array", 2) end
|
||||
@ -564,6 +696,10 @@ function table.splice(t, start_idx, delete_count, ...)
|
||||
return deleted
|
||||
end
|
||||
|
||||
--- Sorts an array by a key function
|
||||
-- @param t array to sort
|
||||
-- @param key_func function to extract sort key from each element
|
||||
-- @return new sorted array
|
||||
function table.sort_by(t, key_func)
|
||||
if type(t) ~= "table" then error("table.sort_by: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.sort_by: first argument must be an array", 2) end
|
||||
@ -576,6 +712,10 @@ function table.sort_by(t, key_func)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Checks if an array is sorted according to a comparator
|
||||
-- @param t array to check
|
||||
-- @param comp optional comparator function
|
||||
-- @return true if array is sorted
|
||||
function table.is_sorted(t, comp)
|
||||
if type(t) ~= "table" then error("table.is_sorted: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.is_sorted: first argument must be an array", 2) end
|
||||
@ -591,6 +731,9 @@ function table.is_sorted(t, comp)
|
||||
return true
|
||||
end
|
||||
|
||||
--- Returns an array of all keys in a table
|
||||
-- @param t table to extract keys from
|
||||
-- @return array of keys
|
||||
function table.keys(t)
|
||||
if type(t) ~= "table" then error("table.keys: argument must be a table", 2) end
|
||||
|
||||
@ -601,6 +744,9 @@ function table.keys(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Returns an array of all values in a table
|
||||
-- @param t table to extract values from
|
||||
-- @return array of values
|
||||
function table.values(t)
|
||||
if type(t) ~= "table" then error("table.values: argument must be a table", 2) end
|
||||
|
||||
@ -611,6 +757,9 @@ function table.values(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Returns an array of [key, value] pairs
|
||||
-- @param t table to convert to pairs
|
||||
-- @return array of [key, value] arrays
|
||||
function table.pairs(t)
|
||||
if type(t) ~= "table" then error("table.pairs: argument must be a table", 2) end
|
||||
|
||||
@ -621,6 +770,9 @@ function table.pairs(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Merges multiple tables into a new table
|
||||
-- @param ... tables to merge
|
||||
-- @return new table with all key-value pairs
|
||||
function table.merge(...)
|
||||
local tables = {...}
|
||||
if #tables == 0 then return {} end
|
||||
@ -640,6 +792,10 @@ function table.merge(...)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Extends the first table with key-value pairs from other tables
|
||||
-- @param t1 table to extend
|
||||
-- @param ... tables to merge into t1
|
||||
-- @return t1 (modified)
|
||||
function table.extend(t1, ...)
|
||||
if type(t1) ~= "table" then error("table.extend: first argument must be a table", 2) end
|
||||
|
||||
@ -658,6 +814,9 @@ function table.extend(t1, ...)
|
||||
return t1
|
||||
end
|
||||
|
||||
--- Creates a table with keys and values swapped
|
||||
-- @param t table to invert
|
||||
-- @return new table with values as keys and keys as values
|
||||
function table.invert(t)
|
||||
if type(t) ~= "table" then error("table.invert: argument must be a table", 2) end
|
||||
|
||||
@ -668,6 +827,10 @@ function table.invert(t)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Creates a new table with only specified keys
|
||||
-- @param t table to pick from
|
||||
-- @param ... keys to include
|
||||
-- @return new table with only specified keys
|
||||
function table.pick(t, ...)
|
||||
if type(t) ~= "table" then error("table.pick: first argument must be a table", 2) end
|
||||
|
||||
@ -683,6 +846,10 @@ function table.pick(t, ...)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Creates a new table excluding specified keys
|
||||
-- @param t table to omit from
|
||||
-- @param ... keys to exclude
|
||||
-- @return new table without specified keys
|
||||
function table.omit(t, ...)
|
||||
if type(t) ~= "table" then error("table.omit: first argument must be a table", 2) end
|
||||
|
||||
@ -701,6 +868,10 @@ function table.omit(t, ...)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Deep equality comparison between two tables
|
||||
-- @param t1 first table
|
||||
-- @param t2 second table
|
||||
-- @return true if tables are deeply equal
|
||||
function table.deep_equals(t1, t2)
|
||||
if type(t1) ~= "table" then error("table.deep_equals: first argument must be a table", 2) end
|
||||
if type(t2) ~= "table" then error("table.deep_equals: second argument must be a table", 2) end
|
||||
@ -739,6 +910,10 @@ function table.deep_equals(t1, t2)
|
||||
return equals_recursive(t1, t2, {})
|
||||
end
|
||||
|
||||
--- Flattens nested arrays to specified depth
|
||||
-- @param t array to flatten
|
||||
-- @param depth maximum depth to flatten (default 1)
|
||||
-- @return new flattened array
|
||||
function table.flatten(t, depth)
|
||||
if type(t) ~= "table" then error("table.flatten: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.flatten: first argument must be an array", 2) end
|
||||
@ -766,6 +941,9 @@ function table.flatten(t, depth)
|
||||
return flatten_recursive(t, depth)
|
||||
end
|
||||
|
||||
--- Deep merges multiple tables, combining nested tables
|
||||
-- @param ... tables to deep merge
|
||||
-- @return new table with deeply merged contents
|
||||
function table.deep_merge(...)
|
||||
local tables = {...}
|
||||
if #tables == 0 then return {} end
|
||||
@ -795,6 +973,10 @@ function table.deep_merge(...)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Splits an array into chunks of specified size
|
||||
-- @param t array to chunk
|
||||
-- @param size size of each chunk
|
||||
-- @return array of chunks
|
||||
function table.chunk(t, size)
|
||||
if type(t) ~= "table" then error("table.chunk: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.chunk: first argument must be an array", 2) end
|
||||
@ -816,6 +998,10 @@ function table.chunk(t, size)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Splits a table into two based on a predicate
|
||||
-- @param t table to partition
|
||||
-- @param predicate function(value, key, table) -> boolean
|
||||
-- @return two tables: elements that pass and elements that fail
|
||||
function table.partition(t, predicate)
|
||||
if type(t) ~= "table" then error("table.partition: first argument must be a table", 2) end
|
||||
if type(predicate) ~= "function" then error("table.partition: second argument must be a function", 2) end
|
||||
@ -843,6 +1029,10 @@ function table.partition(t, predicate)
|
||||
return truthy, falsy
|
||||
end
|
||||
|
||||
--- Groups table elements by a key function
|
||||
-- @param t table to group
|
||||
-- @param key_func function(value, key, table) -> group_key
|
||||
-- @return table where keys are group keys and values are grouped elements
|
||||
function table.group_by(t, key_func)
|
||||
if type(t) ~= "table" then error("table.group_by: first argument must be a table", 2) end
|
||||
if type(key_func) ~= "function" then error("table.group_by: second argument must be a function", 2) end
|
||||
@ -865,6 +1055,9 @@ function table.group_by(t, key_func)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Combines multiple arrays element-wise into tuples
|
||||
-- @param ... arrays to zip together
|
||||
-- @return array of tuples
|
||||
function table.zip(...)
|
||||
local arrays = {...}
|
||||
if #arrays == 0 then error("table.zip: at least one argument required", 2) end
|
||||
@ -895,6 +1088,9 @@ function table.zip(...)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Removes falsy values (nil and false) from a table
|
||||
-- @param t table to compact
|
||||
-- @return new table with only truthy values
|
||||
function table.compact(t)
|
||||
if type(t) ~= "table" then error("table.compact: argument must be a table", 2) end
|
||||
|
||||
@ -925,6 +1121,10 @@ function table.compact(t)
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a random sample of elements from an array
|
||||
-- @param t array to sample from
|
||||
-- @param n number of elements to sample (default 1)
|
||||
-- @return array with sampled elements
|
||||
function table.sample(t, n)
|
||||
if type(t) ~= "table" then error("table.sample: first argument must be a table", 2) end
|
||||
if not table.is_array(t) then error("table.sample: first argument must be an array", 2) end
|
||||
@ -940,6 +1140,11 @@ function table.sample(t, n)
|
||||
return table.slice(shuffled, 1, n)
|
||||
end
|
||||
|
||||
--- Folds a table using an accumulator function
|
||||
-- @param t table to fold
|
||||
-- @param folder function(accumulator, value, key, table) -> new_accumulator
|
||||
-- @param initial initial accumulator value
|
||||
-- @return final accumulator value
|
||||
function table.fold(t, folder, initial)
|
||||
if type(t) ~= "table" then error("table.fold: first argument must be a table", 2) end
|
||||
if type(folder) ~= "function" then error("table.fold: second argument must be a function", 2) end
|
||||
|
@ -883,5 +883,29 @@ test("Statistical Analysis", function()
|
||||
assert_close(83.4, class_average, 0.1)
|
||||
end)
|
||||
|
||||
test("Table Metatable Method Chaining", function()
|
||||
local t = {1, 2, 3, 4, 5}
|
||||
|
||||
-- Check if methods are available directly on table instances
|
||||
assert_equal("function", type(t.filter), "table should have filter method via metatable")
|
||||
assert_equal("function", type(t.map), "table should have map method via metatable")
|
||||
assert_equal("function", type(t.length), "table should have length method via metatable")
|
||||
|
||||
-- Test actual method chaining
|
||||
local result = t:filter(function(v) return v > 2 end)
|
||||
:map(function(v) return v * 2 end)
|
||||
|
||||
assert_table_equal({6, 8, 10}, result)
|
||||
|
||||
-- Test chaining with method calls
|
||||
local nums = {1, 2, 3, 4, 5}
|
||||
local sum = nums:sum()
|
||||
assert_equal(15, sum)
|
||||
|
||||
local sizes = {a = 1, b = 2}
|
||||
local size = sizes:size()
|
||||
assert_equal(2, size)
|
||||
end)
|
||||
|
||||
summary()
|
||||
test_exit()
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"session:x5joQraQyEkfzzRMrcP4o8yK0xjgwtCW": "{\"todos\":[{\"text\":\"asdasd\",\"completed\":true,\"id\":\"1753414744_8147\",\"created_at\":1753414744},{\"text\":\"fsdf\",\"completed\":true,\"id\":\"1753414748_8147\",\"created_at\":1753414748},{\"text\":\"asdasd\",\"completed\":false,\"id\":\"1753415063_8147\",\"created_at\":1753415063},{\"id\":\"1753415066_8147\",\"completed\":false,\"text\":\"asdkjfhaslkjdhflkasjhdf\",\"created_at\":1753415066},{\"text\":\"alsdhnfpuihawepiufhbpioweHBFIOEWBSF\",\"completed\":false,\"id\":\"1753415069_8147\",\"created_at\":1753415069}]}"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user