require("tests") -- Test data local simple_array = {1, 2, 3, 4, 5} local simple_table = {a = 1, b = 2, c = 3} local mixed_table = {1, 2, a = "hello", b = "world"} local nested_table = { a = {x = 1, y = 2}, b = {x = 3, y = 4}, c = {1, 2, 3} } -- ====================================================================== -- BUILT-IN TABLE FUNCTIONS -- ====================================================================== test("Table Insert Operations", function() local t = {1, 2, 3} table.insert(t, 4) assert_equal(4, #t) assert_equal(4, t[4]) table.insert(t, 2, "inserted") assert_equal(5, #t) assert_equal("inserted", t[2]) assert_equal(2, t[3]) end) test("Table Remove Operations", function() local t = {1, 2, 3, 4, 5} local removed = table.remove(t) assert_equal(5, removed) assert_equal(4, #t) removed = table.remove(t, 2) assert_equal(2, removed) assert_equal(3, #t) assert_equal(3, t[2]) end) test("Table Concat", function() local t = {"hello", "world", "test"} assert_equal("helloworldtest", table.concat(t)) assert_equal("hello,world,test", table.concat(t, ",")) assert_equal("world,test", table.concat(t, ",", 2)) assert_equal("world", table.concat(t, ",", 2, 2)) end) test("Table Sort", function() local t = {3, 1, 4, 1, 5} table.sort(t) assert_table_equal({1, 1, 3, 4, 5}, t) local t2 = {"c", "a", "b"} table.sort(t2) assert_table_equal({"a", "b", "c"}, t2) local t3 = {3, 1, 4, 1, 5} table.sort(t3, function(a, b) return a > b end) assert_table_equal({5, 4, 3, 1, 1}, t3) end) -- ====================================================================== -- BASIC TABLE OPERATIONS -- ====================================================================== test("Table Length and Size", function() assert_equal(5, table.length(simple_array)) assert_equal(0, table.length({})) assert_equal(3, table.size(simple_table)) assert_equal(4, table.size(mixed_table)) assert_equal(0, table.size({})) end) test("Table Empty Check", function() assert_equal(true, table.is_empty({})) assert_equal(false, table.is_empty(simple_array)) assert_equal(false, table.is_empty(simple_table)) end) test("Table Array Check", function() assert_equal(true, table.is_array(simple_array)) assert_equal(true, table.is_array({})) assert_equal(false, table.is_array(simple_table)) assert_equal(false, table.is_array(mixed_table)) assert_equal(true, table.is_array({1, 2, 3})) assert_equal(false, table.is_array({1, 2, nil, 4})) assert_equal(false, table.is_array({[0] = 1, [1] = 2})) end) test("Table Clear", function() local t = table.clone(simple_table) table.clear(t) assert_equal(true, table.is_empty(t)) end) test("Table Clone", function() local cloned = table.clone(simple_table) assert_table_equal(simple_table, cloned) -- Modify original shouldn't affect clone simple_table.new_key = "test" assert_equal(nil, cloned.new_key) simple_table.new_key = nil end) test("Table Deep Copy", function() local copied = table.deep_copy(nested_table) assert_table_equal(nested_table, copied) -- Modify nested part shouldn't affect copy nested_table.a.z = 99 assert_equal(nil, copied.a.z) nested_table.a.z = nil end) -- ====================================================================== -- SEARCHING AND FINDING -- ====================================================================== test("Table Contains", function() assert_equal(true, table.contains(simple_array, 3)) assert_equal(false, table.contains(simple_array, 6)) assert_equal(true, table.contains(simple_table, 2)) assert_equal(false, table.contains(simple_table, "hello")) end) test("Table Index Of", function() assert_equal(3, table.index_of(simple_array, 3)) assert_equal(nil, table.index_of(simple_array, 6)) assert_equal("b", table.index_of(simple_table, 2)) assert_equal(nil, table.index_of(simple_table, "hello")) end) test("Table Find", function() local value, key = table.find(simple_array, function(v) return v > 3 end) assert_equal(4, value) assert_equal(4, key) local value2, key2 = table.find(simple_table, function(v, k) return k == "b" end) assert_equal(2, value2) assert_equal("b", key2) local value3 = table.find(simple_array, function(v) return v > 10 end) assert_equal(nil, value3) end) test("Table Find Index", function() local idx = table.find_index(simple_array, function(v) return v > 3 end) assert_equal(4, idx) local idx2 = table.find_index(simple_table, function(v, k) return k == "c" end) assert_equal("c", idx2) local idx3 = table.find_index(simple_array, function(v) return v > 10 end) assert_equal(nil, idx3) end) test("Table Count", function() local arr = {1, 2, 3, 2, 4, 2} assert_equal(3, table.count(arr, 2)) assert_equal(0, table.count(arr, 5)) assert_equal(2, table.count(arr, function(v) return v > 2 end)) assert_equal(2, table.count(arr, function(v) return v == 1 or v == 4 end)) end) -- ====================================================================== -- FILTERING AND MAPPING -- ====================================================================== test("Table Filter", function() local evens = table.filter(simple_array, function(v) return v % 2 == 0 end) assert_table_equal({2, 4}, evens) local filtered_table = table.filter(simple_table, function(v) return v > 1 end) assert_equal(2, table.size(filtered_table)) assert_equal(2, filtered_table.b) assert_equal(3, filtered_table.c) end) test("Table Reject", function() local odds = table.reject(simple_array, function(v) return v % 2 == 0 end) assert_table_equal({1, 3, 5}, odds) end) test("Table Map", function() local doubled = table.map(simple_array, function(v) return v * 2 end) assert_table_equal({2, 4, 6, 8, 10}, doubled) local mapped_table = table.map(simple_table, function(v) return v + 10 end) assert_equal(11, mapped_table.a) assert_equal(12, mapped_table.b) assert_equal(13, mapped_table.c) end) test("Table Map Values", function() local incremented = table.map_values(simple_table, function(v) return v + 1 end) assert_equal(2, incremented.a) assert_equal(3, incremented.b) assert_equal(4, incremented.c) end) test("Table Map Keys", function() local prefixed = table.map_keys(simple_table, function(k) return "key_" .. k end) assert_equal(1, prefixed.key_a) assert_equal(2, prefixed.key_b) assert_equal(3, prefixed.key_c) assert_equal(nil, prefixed.a) end) -- ====================================================================== -- REDUCING AND AGGREGATING -- ====================================================================== test("Table Reduce", function() local sum = table.reduce(simple_array, function(acc, v) return acc + v end) assert_equal(15, sum) local sum_with_initial = table.reduce(simple_array, function(acc, v) return acc + v end, 10) assert_equal(25, sum_with_initial) local product = table.reduce({2, 3, 4}, function(acc, v) return acc * v end) assert_equal(24, product) end) test("Table Fold", function() local sum = table.fold(simple_array, function(acc, v) return acc + v end, 0) assert_equal(15, sum) local concatenated = table.fold({"a", "b", "c"}, function(acc, v) return acc .. v end, "") assert_equal("abc", concatenated) end) test("Table Math Operations", function() assert_equal(15, table.sum(simple_array)) assert_equal(120, table.product(simple_array)) assert_equal(1, table.min(simple_array)) assert_equal(5, table.max(simple_array)) assert_equal(3, table.average(simple_array)) local floats = {1.5, 2.5, 3.0} assert_close(7.0, table.sum(floats)) assert_close(2.33333, table.average(floats), 0.001) end) -- ====================================================================== -- BOOLEAN OPERATIONS -- ====================================================================== test("Table All", function() assert_equal(true, table.all({true, true, true})) assert_equal(false, table.all({true, false, true})) assert_equal(true, table.all({})) assert_equal(true, table.all(simple_array, function(v) return v > 0 end)) assert_equal(false, table.all(simple_array, function(v) return v > 3 end)) end) test("Table Any", function() assert_equal(true, table.any({false, true, false})) assert_equal(false, table.any({false, false, false})) assert_equal(false, table.any({})) assert_equal(true, table.any(simple_array, function(v) return v > 3 end)) assert_equal(false, table.any(simple_array, function(v) return v > 10 end)) end) test("Table None", function() assert_equal(true, table.none({false, false, false})) assert_equal(false, table.none({false, true, false})) assert_equal(true, table.none({})) assert_equal(false, table.none(simple_array, function(v) return v > 3 end)) assert_equal(true, table.none(simple_array, function(v) return v > 10 end)) end) -- ====================================================================== -- SET OPERATIONS -- ====================================================================== test("Table Unique", function() local duplicates = {1, 2, 2, 3, 3, 3, 4} local unique = table.unique(duplicates) assert_table_equal({1, 2, 3, 4}, unique) local empty_unique = table.unique({}) assert_table_equal({}, empty_unique) end) test("Table Intersection", function() local arr1 = {1, 2, 3, 4} local arr2 = {3, 4, 5, 6} local intersect = table.intersection(arr1, arr2) assert_equal(2, #intersect) assert_equal(true, table.contains(intersect, 3)) assert_equal(true, table.contains(intersect, 4)) end) test("Table Union", function() local arr1 = {1, 2, 3} local arr2 = {3, 4, 5} local union = table.union(arr1, arr2) assert_equal(5, #union) for i = 1, 5 do assert_equal(true, table.contains(union, i)) end end) test("Table Difference", function() local arr1 = {1, 2, 3, 4, 5} local arr2 = {3, 4} local diff = table.difference(arr1, arr2) assert_table_equal({1, 2, 5}, diff) end) -- ====================================================================== -- ARRAY OPERATIONS -- ====================================================================== test("Table Reverse", function() local reversed = table.reverse(simple_array) assert_table_equal({5, 4, 3, 2, 1}, reversed) local single = table.reverse({42}) assert_table_equal({42}, single) local empty = table.reverse({}) assert_table_equal({}, empty) end) test("Table Shuffle", function() local shuffled = table.shuffle(simple_array) assert_equal(5, #shuffled) -- All original elements should still be present for _, v in ipairs(simple_array) do assert_equal(true, table.contains(shuffled, v)) end -- Should be same length assert_equal(#simple_array, #shuffled) end) test("Table Rotate", function() local arr = {1, 2, 3, 4, 5} local rotated_right = table.rotate(arr, 2) assert_table_equal({4, 5, 1, 2, 3}, rotated_right) local rotated_left = table.rotate(arr, -2) assert_table_equal({3, 4, 5, 1, 2}, rotated_left) local no_rotation = table.rotate(arr, 0) assert_table_equal(arr, no_rotation) local full_rotation = table.rotate(arr, 5) assert_table_equal(arr, full_rotation) end) test("Table Slice", function() local sliced = table.slice(simple_array, 2, 4) assert_table_equal({2, 3, 4}, sliced) local from_start = table.slice(simple_array, 1, 3) assert_table_equal({1, 2, 3}, from_start) local to_end = table.slice(simple_array, 3) assert_table_equal({3, 4, 5}, to_end) local negative_indices = table.slice(simple_array, -3, -1) assert_table_equal({3, 4, 5}, negative_indices) end) test("Table Splice", function() local arr = {1, 2, 3, 4, 5} -- Remove elements local removed = table.splice(arr, 2, 2) assert_table_equal({2, 3}, removed) assert_table_equal({1, 4, 5}, arr) -- Insert elements arr = {1, 2, 3, 4, 5} removed = table.splice(arr, 3, 0, "a", "b") assert_table_equal({}, removed) assert_table_equal({1, 2, "a", "b", 3, 4, 5}, arr) -- Replace elements arr = {1, 2, 3, 4, 5} removed = table.splice(arr, 2, 2, "x", "y", "z") assert_table_equal({2, 3}, removed) assert_table_equal({1, "x", "y", "z", 4, 5}, arr) end) -- ====================================================================== -- SORTING HELPERS -- ====================================================================== test("Table Sort By", function() local people = { {name = "Alice", age = 30}, {name = "Bob", age = 25}, {name = "Charlie", age = 35} } local sorted_by_age = table.sort_by(people, function(p) return p.age end) assert_equal("Bob", sorted_by_age[1].name) assert_equal("Charlie", sorted_by_age[3].name) local sorted_by_name = table.sort_by(people, function(p) return p.name end) assert_equal("Alice", sorted_by_name[1].name) assert_equal("Charlie", sorted_by_name[3].name) end) test("Table Is Sorted", function() assert_equal(true, table.is_sorted({1, 2, 3, 4, 5})) assert_equal(false, table.is_sorted({1, 3, 2, 4, 5})) assert_equal(true, table.is_sorted({})) assert_equal(true, table.is_sorted({42})) assert_equal(true, table.is_sorted({5, 4, 3, 2, 1}, function(a, b) return a > b end)) assert_equal(false, table.is_sorted({1, 2, 3, 4, 5}, function(a, b) return a > b end)) end) -- ====================================================================== -- UTILITY FUNCTIONS -- ====================================================================== test("Table Keys and Values", function() local keys = table.keys(simple_table) assert_equal(3, #keys) assert_equal(true, table.contains(keys, "a")) assert_equal(true, table.contains(keys, "b")) assert_equal(true, table.contains(keys, "c")) local values = table.values(simple_table) assert_equal(3, #values) assert_equal(true, table.contains(values, 1)) assert_equal(true, table.contains(values, 2)) assert_equal(true, table.contains(values, 3)) end) test("Table Pairs", function() local pairs_list = table.pairs({a = 1, b = 2}) assert_equal(2, #pairs_list) -- Should contain key-value pairs local found_a, found_b = false, false for _, pair in ipairs(pairs_list) do if pair[1] == "a" and pair[2] == 1 then found_a = true end if pair[1] == "b" and pair[2] == 2 then found_b = true end end assert_equal(true, found_a) assert_equal(true, found_b) end) test("Table Merge", function() local t1 = {a = 1, b = 2} local t2 = {c = 3, d = 4} local t3 = {b = 20, e = 5} local merged = table.merge(t1, t2, t3) assert_equal(5, table.size(merged)) assert_equal(1, merged.a) assert_equal(20, merged.b) -- Last one wins assert_equal(3, merged.c) assert_equal(4, merged.d) assert_equal(5, merged.e) end) test("Table Extend", function() local t1 = {a = 1, b = 2} local t2 = {c = 3, d = 4} local extended = table.extend(t1, t2) assert_equal(t1, extended) -- Should return t1 assert_equal(4, table.size(t1)) assert_equal(3, t1.c) assert_equal(4, t1.d) end) test("Table Invert", function() local inverted = table.invert(simple_table) assert_equal("a", inverted[1]) assert_equal("b", inverted[2]) assert_equal("c", inverted[3]) end) test("Table Pick and Omit", function() local big_table = {a = 1, b = 2, c = 3, d = 4, e = 5} local picked = table.pick(big_table, "a", "c", "e") assert_equal(3, table.size(picked)) assert_equal(1, picked.a) assert_equal(3, picked.c) assert_equal(5, picked.e) assert_equal(nil, picked.b) assert_equal(nil, picked.d) local omitted = table.omit(big_table, "b", "d") assert_equal(3, table.size(omitted)) assert_equal(1, omitted.a) assert_equal(3, omitted.c) assert_equal(5, omitted.e) assert_equal(nil, omitted.b) assert_equal(nil, omitted.d) end) -- ====================================================================== -- DEEP OPERATIONS -- ====================================================================== test("Table Deep Equals", function() local t1 = {a = {x = 1, y = 2}, b = {1, 2, 3}} local t2 = {a = {x = 1, y = 2}, b = {1, 2, 3}} local t3 = {a = {x = 1, y = 3}, b = {1, 2, 3}} assert_equal(true, table.deep_equals(t1, t2)) assert_equal(false, table.deep_equals(t1, t3)) assert_equal(true, table.deep_equals({}, {})) assert_equal(false, table.deep_equals({a = 1}, {a = 1, b = 2})) end) test("Table Flatten", function() local nested = {{1, 2}, {3, 4}, {5, {6, 7}}} local flattened = table.flatten(nested) assert_table_equal({1, 2, 3, 4, 5, {6, 7}}, flattened) local deep_flattened = table.flatten(nested, 2) assert_table_equal({1, 2, 3, 4, 5, 6, 7}, deep_flattened) local already_flat = table.flatten({1, 2, 3}) assert_table_equal({1, 2, 3}, already_flat) end) test("Table Deep Merge", function() local t1 = {a = {x = 1}, b = 2} local t2 = {a = {y = 3}, c = 4} local merged = table.deep_merge(t1, t2) assert_equal(1, merged.a.x) assert_equal(3, merged.a.y) assert_equal(2, merged.b) assert_equal(4, merged.c) -- Original tables should be unchanged assert_equal(nil, t1.a.y) assert_equal(nil, t1.c) end) -- ====================================================================== -- ADVANCED OPERATIONS -- ====================================================================== test("Table Chunk", function() local chunks = table.chunk({1, 2, 3, 4, 5, 6, 7}, 3) assert_equal(3, #chunks) assert_table_equal({1, 2, 3}, chunks[1]) assert_table_equal({4, 5, 6}, chunks[2]) assert_table_equal({7}, chunks[3]) local exact_chunks = table.chunk({1, 2, 3, 4}, 2) assert_equal(2, #exact_chunks) assert_table_equal({1, 2}, exact_chunks[1]) assert_table_equal({3, 4}, exact_chunks[2]) end) test("Table Partition", function() local evens, odds = table.partition(simple_array, function(v) return v % 2 == 0 end) assert_table_equal({2, 4}, evens) assert_table_equal({1, 3, 5}, odds) local empty_true, all_false = table.partition({1, 3, 5}, function(v) return v % 2 == 0 end) assert_table_equal({}, empty_true) assert_table_equal({1, 3, 5}, all_false) end) test("Table Group By", function() local people = { {name = "Alice", department = "engineering"}, {name = "Bob", department = "sales"}, {name = "Charlie", department = "engineering"}, {name = "David", department = "sales"} } local by_dept = table.group_by(people, function(person) return person.department end) assert_equal(2, table.size(by_dept)) assert_equal(2, #by_dept.engineering) assert_equal(2, #by_dept.sales) assert_equal("Alice", by_dept.engineering[1].name) assert_equal("Bob", by_dept.sales[1].name) end) test("Table Zip", function() local names = {"Alice", "Bob", "Charlie"} local ages = {25, 30, 35} local cities = {"NYC", "LA", "Chicago"} local zipped = table.zip(names, ages, cities) assert_equal(3, #zipped) assert_table_equal({"Alice", 25, "NYC"}, zipped[1]) assert_table_equal({"Bob", 30, "LA"}, zipped[2]) assert_table_equal({"Charlie", 35, "Chicago"}, zipped[3]) -- Different lengths local short_zip = table.zip({1, 2, 3}, {"a", "b"}) assert_equal(2, #short_zip) assert_table_equal({1, "a"}, short_zip[1]) assert_table_equal({2, "b"}, short_zip[2]) end) test("Table Compact", function() local messy = {1, nil, false, 2, nil, 3, false} local compacted = table.compact(messy) assert_table_equal({1, 2, 3}, compacted) local clean = {1, 2, 3} local unchanged = table.compact(clean) assert_table_equal(clean, unchanged) end) test("Table Sample", function() local sample1 = table.sample(simple_array, 3) assert_equal(3, #sample1) -- All sampled elements should be from original for _, v in ipairs(sample1) do assert_equal(true, table.contains(simple_array, v)) end local single_sample = table.sample(simple_array) assert_equal(1, #single_sample) assert_equal(true, table.contains(simple_array, single_sample[1])) local oversample = table.sample({1, 2}, 5) assert_equal(2, #oversample) end) -- ====================================================================== -- EDGE CASES AND ERROR HANDLING -- ====================================================================== test("Empty Table Handling", function() local empty = {} assert_equal(true, table.is_empty(empty)) assert_equal(0, table.length(empty)) assert_equal(0, table.size(empty)) assert_equal(true, table.is_array(empty)) assert_table_equal({}, table.filter(empty, function() return true end)) assert_table_equal({}, table.map(empty, function(v) return v * 2 end)) assert_table_equal({}, table.keys(empty)) assert_table_equal({}, table.values(empty)) assert_equal(true, table.all(empty)) assert_equal(false, table.any(empty)) assert_equal(true, table.none(empty)) end) test("Single Element Tables", function() local single = {42} assert_equal(1, table.length(single)) assert_equal(1, table.size(single)) assert_equal(true, table.is_array(single)) assert_equal(false, table.is_empty(single)) assert_equal(42, table.sum(single)) assert_equal(42, table.product(single)) assert_equal(42, table.min(single)) assert_equal(42, table.max(single)) assert_equal(42, table.average(single)) assert_table_equal({42}, table.reverse(single)) assert_table_equal({84}, table.map(single, function(v) return v * 2 end)) end) test("Circular Reference Handling", function() local t1 = {a = 1} local t2 = {b = 2} t1.ref = t2 t2.ref = t1 -- Deep copy should handle circular references local copied = table.deep_copy(t1) assert_equal(1, copied.a) assert_equal(2, copied.ref.b) assert_equal(copied, copied.ref.ref) -- Should maintain circular structure end) test("Large Table Performance", function() local large = {} for i = 1, 10000 do large[i] = i end assert_equal(10000, table.length(large)) assert_equal(true, table.is_array(large)) assert_equal(50005000, table.sum(large)) -- Sum of 1 to 10000 local evens = table.filter(large, function(v) return v % 2 == 0 end) assert_equal(5000, #evens) local doubled = table.map(large, function(v) return v * 2 end) assert_equal(10000, #doubled) assert_equal(2, doubled[1]) assert_equal(20000, doubled[10000]) end) test("Mixed Type Table Handling", function() local mixed = {1, "hello", true, {a = 1}, function() end} assert_equal(5, table.length(mixed)) assert_equal(true, table.is_array(mixed)) assert_equal(true, table.contains(mixed, "hello")) assert_equal(true, table.contains(mixed, true)) local strings_only = table.filter(mixed, function(v) return type(v) == "string" end) assert_equal(1, #strings_only) assert_equal("hello", strings_only[1]) end) -- ====================================================================== -- PERFORMANCE TESTS -- ====================================================================== test("Performance Test", function() local large_array = {} for i = 1, 10000 do large_array[i] = math.random(1, 1000) end local start = os.clock() local filtered = table.filter(large_array, function(v) return v > 500 end) local filter_time = os.clock() - start start = os.clock() local mapped = table.map(large_array, function(v) return v * 2 end) local map_time = os.clock() - start start = os.clock() local sum = table.sum(large_array) local sum_time = os.clock() - start start = os.clock() local sorted = table.sort_by(large_array, function(v) return v end) local sort_time = os.clock() - start start = os.clock() local unique = table.unique(large_array) local unique_time = os.clock() - start print(string.format(" Filter %d elements: %.3fs", #filtered, filter_time)) print(string.format(" Map %d elements: %.3fs", #mapped, map_time)) print(string.format(" Sum %d elements: %.3fs", #large_array, sum_time)) print(string.format(" Sort %d elements: %.3fs", #sorted, sort_time)) print(string.format(" Unique from %d to %d: %.3fs", #large_array, #unique, unique_time)) assert(#filtered > 0, "should filter some elements") assert_equal(#large_array, #mapped) assert(sum > 0, "sum should be positive") assert_equal(#large_array, #sorted) assert(table.is_sorted(sorted), "should be sorted") end) -- ====================================================================== -- INTEGRATION TESTS -- ====================================================================== test("Data Processing Pipeline", function() local sales_data = { {product = "laptop", price = 1000, quantity = 2, category = "electronics"}, {product = "mouse", price = 25, quantity = 10, category = "electronics"}, {product = "book", price = 15, quantity = 5, category = "books"}, {product = "phone", price = 800, quantity = 3, category = "electronics"}, {product = "magazine", price = 5, quantity = 20, category = "books"} } -- Calculate total revenue per item local with_revenue = table.map(sales_data, function(item) local new_item = table.clone(item) new_item.revenue = item.price * item.quantity return new_item end) -- Filter high-value items (revenue >= 100) local high_value = table.filter(with_revenue, function(item) return item.revenue >= 100 end) -- Group by category local by_category = table.group_by(high_value, function(item) return item.category end) -- Calculate total revenue by category local category_totals = table.map_values(by_category, function(items) return table.sum(table.map(items, function(item) return item.revenue end)) end) assert_equal(2, table.size(category_totals)) assert_equal(4650, category_totals.electronics) -- laptop: 2000, mouse: 250, phone: 2400 assert_equal(100, category_totals.books) -- magazine: 100 end) test("Complex Data Transformation", function() local users = { {id = 1, name = "Alice", age = 25, skills = {"lua", "python"}}, {id = 2, name = "Bob", age = 30, skills = {"javascript", "lua"}}, {id = 3, name = "Charlie", age = 35, skills = {"python", "java"}}, {id = 4, name = "David", age = 28, skills = {"lua", "go"}} } -- Find Lua developers local lua_devs = table.filter(users, function(user) return table.contains(user.skills, "lua") end) -- Sort by age local sorted_lua_devs = table.sort_by(lua_devs, function(user) return user.age end) -- Extract just names and ages local simplified = table.map(sorted_lua_devs, function(user) return {name = user.name, age = user.age} end) assert_equal(3, #simplified) assert_equal("Alice", simplified[1].name) -- Youngest assert_equal("David", simplified[2].name) assert_equal("Bob", simplified[3].name) -- Oldest -- Group all users by age ranges local age_groups = table.group_by(users, function(user) if user.age < 30 then return "young" else return "experienced" end end) assert_equal(2, #age_groups.young) -- Alice, David assert_equal(2, #age_groups.experienced) -- Bob, Charlie end) test("Statistical Analysis", function() local test_scores = { {student = "Alice", scores = {85, 92, 78, 95, 88}}, {student = "Bob", scores = {72, 85, 90, 77, 82}}, {student = "Charlie", scores = {95, 88, 92, 90, 85}}, {student = "David", scores = {68, 75, 80, 72, 78}} } -- Calculate average score for each student local with_averages = table.map(test_scores, function(student) local avg = table.average(student.scores) return { student = student.student, scores = student.scores, average = avg, max_score = table.max(student.scores), min_score = table.min(student.scores) } end) -- Find top performer local top_student = table.reduce(with_averages, function(best, current) return current.average > best.average and current or best end) -- Students above class average local all_averages = table.map(with_averages, function(s) return s.average end) local class_average = table.average(all_averages) local above_average = table.filter(with_averages, function(s) return s.average > class_average end) assert_equal("Charlie", top_student.student) assert_equal(90, top_student.average) assert_equal(2, #above_average) -- Charlie and Alice 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()