Lua: table.select API
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
||||
type LuaValue,
|
||||
luaValueToJS,
|
||||
} from "../runtime.ts";
|
||||
import { asyncQuickSort } from "../util.ts";
|
||||
import { asyncQuickSort, evalPromiseValues } from "../util.ts";
|
||||
|
||||
export const tableApi = new LuaTable({
|
||||
/**
|
||||
@@ -99,6 +99,7 @@ export const tableApi = new LuaTable({
|
||||
),
|
||||
/**
|
||||
* Returns the keys of a table.
|
||||
* Note: Space Lua specific
|
||||
* @param tbl - The table to get the keys from.
|
||||
* @returns The keys of the table.
|
||||
*/
|
||||
@@ -111,6 +112,7 @@ export const tableApi = new LuaTable({
|
||||
}),
|
||||
/**
|
||||
* Checks if a table (used as an array) contains a value.
|
||||
* Note: Space Lua specific
|
||||
* @param tbl - The table to check.
|
||||
* @param value - The value to check for.
|
||||
* @returns True if the value is in the table, false otherwise.
|
||||
@@ -138,6 +140,34 @@ export const tableApi = new LuaTable({
|
||||
}
|
||||
},
|
||||
),
|
||||
/**
|
||||
* Returns a new table from an old one, only with selected keys
|
||||
* @param tbl a Lua table or JS object
|
||||
* @param keys a list of keys to select from the table, if keys[0] is a table or array, assumed to contain the keys to select
|
||||
* @returns a new table with only the selected keys
|
||||
*/
|
||||
select: new LuaBuiltinFunction(
|
||||
(sf, tbl: LuaTable | Record<string, any>, ...keys: LuaValue[]) => {
|
||||
// Normalize arguments
|
||||
if (Array.isArray(keys[0])) {
|
||||
// First argument is key array, let's unpack
|
||||
keys = keys[0];
|
||||
} else if (keys[0] instanceof LuaTable) {
|
||||
keys = keys[0].toJSArray();
|
||||
}
|
||||
const resultTable = new LuaTable();
|
||||
const setPromises: (void | Promise<void>)[] = [];
|
||||
for (const key of keys) {
|
||||
setPromises.push(resultTable.set(key, luaGet(tbl, key, null, sf)));
|
||||
}
|
||||
const promised = evalPromiseValues(setPromises);
|
||||
if (promised instanceof Promise) {
|
||||
return promised.then(() => resultTable);
|
||||
} else {
|
||||
return resultTable;
|
||||
}
|
||||
},
|
||||
),
|
||||
pack: new LuaBuiltinFunction((_sf, ...args: any[]) => {
|
||||
const tbl = new LuaTable();
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
|
||||
@@ -1,9 +1,37 @@
|
||||
function deepCompare(t1, t2)
|
||||
if t1 == t2 then return true end
|
||||
-- If they are the same object, return true
|
||||
if type(t1) ~= "table" or type(t2) ~= "table" then return false end
|
||||
-- If not both tables, return false
|
||||
-- Check if both tables have the same number of keys
|
||||
local t1_keys = 0
|
||||
local t2_keys = 0
|
||||
for k in pairs(t1) do
|
||||
t1_keys = t1_keys + 1
|
||||
end
|
||||
for k in pairs(t2) do
|
||||
t2_keys = t2_keys + 1
|
||||
end
|
||||
if t1_keys ~= t2_keys then return false end
|
||||
|
||||
-- Recursively compare each key-value pair
|
||||
for k, v in pairs(t1) do
|
||||
if not deepCompare(v, t2[k]) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function assertEqual(a, b)
|
||||
if a ~= b then
|
||||
error("Assertion failed: " .. a .. " is not equal to " .. b)
|
||||
if not deepCompare(a, b) then
|
||||
error("Assertion failed: " .. tostring(a) .. " is not equal to " .. tostring(b))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Basic table operations
|
||||
local t = { 1, 2, 3 }
|
||||
table.insert(t, 4)
|
||||
@@ -155,3 +183,10 @@ local idx, two = table.find(t, function(v) return v == 2 end)
|
||||
assertEqual(idx, 3)
|
||||
assertEqual(two, 2)
|
||||
assertEqual(table.find(t, function(v) return v == 4 end), nil)
|
||||
|
||||
-- Test table.select
|
||||
local tbl = {name = "Pete", age = 100, parents = {"John", "Jane"}}
|
||||
assertEqual(table.select(tbl, "name"), {name = "Pete"})
|
||||
assertEqual(table.select(tbl, {"name"}), {name = "Pete"})
|
||||
assertEqual(table.select(tbl, "name", "age"), { name = "Pete", age = 100})
|
||||
assertEqual(table.select(tbl, "name", "age", "non-existing"), { name = "Pete", age = 100})
|
||||
|
||||
Reference in New Issue
Block a user