Skip to content
Engine

Data

TableKit

More than 80 table helpers for copying, merging, diffing, slicing, grouping and transforming tables without mutating them.

PackageShared

Getting it

local TableKit = Engine:GetPackage("TableKit")

Overview

TableKit collects the table utilities every project ends up writing. All functions are pure: they return a new table and leave the one you pass in untouched (the only exception is freeze, which freezes in place). Functions that take an array work on the array part (1..#t); functions that take a dictionary work on every key.

local TableKit = Engine:GetPackage("TableKit")

local scores = { 40, 95, 12, 70 }
print(TableKit.sum(scores))                -- 217
print(TableKit.max(scores))                -- 95
print(TableKit.take(TableKit.sort(scores, function(a, b) return a > b end), 3)) -- { 95, 70, 40 }

local byTeam = TableKit.groupBy(players, function(player)
	return player.Team.Name
end)

Structure

FunctionDescription
deepCopy(t)Copies every nested table. Handles cycles and shared references.
clone(t)Shallow copy (table.clone).
merge(a, b, deep?)Copy of a with b's keys on top. With deep, nested tables are merged too.
defaults(t, ...fallbacks)Copy of t where missing keys are filled from each fallback in turn.
reconcile(target, template)Shapes target like template: keeps target values whose type matches, fills in missing keys from the template, drops keys the template does not have. Perfect for upgrading saved data to a new format.
diff(a, b)What changed from a to b. Removed keys are marked with TableKit.REMOVE.
patch(a, diff)Applies a diff result to a. patch(a, diff(a, b)) deep-equals b.
freeze(t, deep?)Freezes t (and with deep, every nested table) and returns it.
equals(a, b)Same keys with == values (one level).
deepEquals(a, b)Same structure all the way down. Handles cycles.
tap(t, fn)Calls fn(t) and returns t, for debugging in a chain.
Upgrading saved data with reconcile
local TEMPLATE = { Coins = 0, Level = 1, Settings = { Music = true, Sfx = true } }

local saved = { Coins = 250, Settings = { Music = false } }
local data = TableKit.reconcile(saved, TEMPLATE)
-- { Coins = 250, Level = 1, Settings = { Music = false, Sfx = true } }

Arrays

FunctionDescription
slice(t, i?, j?)Items i to j. Negative indices count from the end.
take(t, n), drop(t, n)The first n items, or everything after them.
takeWhile(t, pred), dropWhile(t, pred)Take or skip items while pred(value, index) is true.
first(t), last(t)The first or last item.
concat(...)All arrays joined.
flatten(t, depth?)Nested arrays flattened depth levels (default from configuration).
reverse(t), rotate(t, n)Reversed, or shifted left by n.
shuffle(t, rng?)Shuffled copy (Fisher-Yates). Pass a Random for repeatable results.
sort(t, comparator?)Sorted copy.
unique(t, keyFn?)Duplicates removed, keeping the first. keyFn decides what counts as the same.
chunk(t, size)Split into arrays of size.
zip(...){ {a1, b1}, {a2, b2}, ... }.
partition(t, pred)Two arrays: items that pass and items that fail.
groupBy(t, fn){ [fn(value)] = { values } }.
countBy(t, fn){ [fn(value)] = count }.
compact(t)Copy without nil holes.
without(t, ...values)Copy without the given values.
difference(t, other), intersection(t, other), union(t, other)Set operations on arrays.
indexOf(t, value), includes(t, value)Find a value.
range(stop) / range(start, stop, step?){ 1, 2, ..., stop } or a stepped range.
times(n, fn){ fn(1), fn(2), ..., fn(n) }.
replicate(value, n)n copies of value.
fill(t, value, i?, j?)Copy with a range set to value.
sample(t, rng?), sampleSize(t, n, rng?)One or n random items.

Numbers

FunctionDescription
sum(t)Sum of the numbers.
average(t)Mean, 0 for an empty array.
min(t, fn?), max(t, fn?)The smallest or largest item. With fn, compares fn(item) and returns the item.

Dictionaries

FunctionDescription
keys(t), values(t)Arrays of keys or values.
count(t), isEmpty(t)Number of keys, and whether there are none.
toArray(t, keyComparator?)Values as an array, ordered by sorted keys when a comparator is given.
pick(t, keys), omit(t, keys)Copy with only, or without, the listed keys.
invert(t)Keys and values swapped.
mapKeys(t, fn), mapValues(t, fn)Transform every key or value.
flattenKeys(t, separator?){ a = { b = 1 } } becomes { ["a.b"] = 1 }.
unflattenKeys(t, separator?)The reverse.
get(t, path, default?, separator?)Read "Settings.Audio.Volume" safely, returning default when a step is missing.
set(t, path, value, separator?)Copy with the value at path set, creating tables along the way.

Functional

FunctionDescription
forEach(t, fn)Calls fn(value, index) for every item.
map(t, fn), filter(t, pred), flatMap(t, fn)The usual.
reduce(t, fn, initial)fn(accumulator, value, index) over every item.
find(t, pred)The first matching value and its index.
every(t, pred), some(t, pred)Whether all or any items match.

Configuration

Defaults from DefaultConfiguration/Packages/TableKit2 settings
SettingDefaultWhat it does
DefaultFlattenDepth1Nesting levels .flatten collapses when no depth is passed (math.huge = fully recursive).
DefaultKeySeparator"."Separator .flattenKeys/.unflattenKeys use between path segments when none is passed.