Skip to content

Tables

A collection of functions that operate on Lua tables. These can operate on arrays, dictionaries and any collection types implemented with tables.

These functions can iterate over any Iterable values.

These functions typically act on immutable tables and return new tables in functional style. Note that mutable arguments in Rodash are explicitly typed as such with the mut keyword.

Functions

all

function dash.all(source, handler) --> bool
Return true if handler returns true for every element in source it is called with.

If no handler is provided, dash.all returns true if every element is non-nil.

Type

<T: Iterable<K,V>>(T, (value: V, key: K -> bool)?) -> bool

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

handler - (value: V, key: K) -> bool? - a function (taking value (the primary value type) and key (the primary key type), and returning a boolean) (optional) - (default = dash.id)

Returns

bool - a boolean

Examples

local names = {
    [3] = "Boromir",
    [1] = "Frodo",
    [8] = "Bilbo"
}
local allNamesStartWithB = dash.all(names, function(name)
    return dash.startsWith(name, "B")
end)
allNamesStartWithB --> false

any

function dash.any(source, handler) --> bool
Return true if handler returns true for at least one element in source it is called with.

If no handler is provided, dash.any returns true if some element is non-nil.

Type

<T: Iterable<K,V>>(T -> bool)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

handler - any - any value - (default = dash.id)

Returns

bool - a boolean

Examples

local names = {
    [3] = "Boromir",
    [1] = "Frodo",
    [8] = "Bilbo"
}
local anyNameStartsWithB = dash.any(names, function(name)
    return dash.startsWith(name, "B")
end)
anyNameStartsWithB --> true

assign

function dash.assign(target, ...) --> T
Adds new elements in target from subsequent table arguments in order, with elements in later tables replacing earlier ones if their keys match.

Type

<T: Iterable<K,V>>(mut T, ...T) -> T

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

target - mut T - the primary type (which can be mutated)

... - ...T - the primary type - any number of other tables

Returns

T - the primary type

Examples

local someInfo = {
    Frodo = {
        name = "Frodo Baggins",
        team = "blue"
    },
    Boromir = {
        score = 5
    }
}
local someOtherInfo = {
    Frodo = {
        team = "red",
        score = 10
    },
    Bilbo = {
        team = "yellow",

    },
    Boromir = {
        score = {1, 2, 3}
    }
}
local assignedInfo = dash.assign(someInfo, someOtherInfo)
--[[
    --> {
        Frodo = {
            team = "red",
            score = 10
        },
        Bilbo = {
            team = "yellow"
        },
        Boromir = {
            score = {1, 2, 3}
        }
    }
]]

See


clone

function dash.clone(source) --> T
Returns a shallow copy of source.

Type

<T: Iterable<K,V>>(T -> T)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

T - the primary type

Examples

local Hermione = {
    name = "Hermione Granger",
    time = 12
}
local PastHermione = dash.clone(Hermione)
PastHermione.time = 9
Hermione.time --> 12

See

  • dash.cloneDeep - if you also want to clone descendants of the table, though this can be costly.

  • dash.map - if you want to return different values for each key.

  • dash.Cloneable - use this to derive a default :clone() method for class instances.


cloneDeep

function dash.cloneDeep(source) --> T
Recursively clones descendants of source, returning the cloned object. If references to the same table are found, the same clone is used in the result. This means that dash.cloneDeep is cycle-safe.

Elements which are not tables are not modified.

Type

<T: Iterable<K,V>>(T -> T)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

T - the primary type

Examples

local Harry = {
    patronus = "stag",
    age = 12
}
local Hedwig = {
    animal = "owl",
    owner = Harry
}
Harry.pet = Hedwig
local clonedHarry = dash.cloneDeep(Harry)
Harry.age = 13
-- The object clonedHarry is completely independent of any changes to Harry:
dash.pretty(clonedHarry) --> '<1>{age = 12, patronus = "stag", pet = {animal = "owl", owner = &1}}'

See

  • dash.clone - if you simply want to perform a shallow clone.

compact

function dash.compact(source) --> V[]
Returns an array of elements from a sparse array source with the returned elements provided in original key-order.

Type

<T: Iterable<K,V>>(T -> V[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

V[] - an array (of the primary value type)

Examples

local names = {
    [3] = "Boromir",
    [1] = "Frodo",
    [8] = "Bilbo"
}
local inOrderNames = dash.compact(names)
inOrderNames --> {"Frodo", "Boromir", "Bilbo"}

deepEqual

function dash.deepEqual(a, b) --> bool
Returns true if every element in a recursively matches every element b.

  • For elements which are not tables, they match if they are equal.
  • If they are tables they match if the left is recursively deeply-equal to the right.

Type

any, any -> bool

Parameters

a - any - any value

b - any - any value

Returns

bool - a boolean

Examples

local car = {
    speed = 10,
    wheels = 4,
    lightsOn = {
        indicators = true,
        headlights = false
    }
}
local car2 = {
    speed = 10,
    wheels = 4,
    lightsOn = {
        indicators = false,
        headlights = false
    }
}
dash.deepEqual(car, {}) --> false
dash.deepEqual(car, car) --> true
dash.deepEqual(car, dash.clone(car)) --> true
dash.deepEqual(car, dash.cloneDeep(car)) --> true
dash.deepEqual(car, car2) --> false

See


defaults

function dash.defaults(target, ...) --> T
Adds new elements in target from subsequent table arguments in order, with elements in earlier tables overriding later ones if their keys match.

Type

<T: Iterable<K,V>>(mut T, ...T) -> T

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

target - mut T - the primary type (which can be mutated)

... - ...T - the primary type - any number of other tables

Returns

T - the primary type

Examples

local someInfo = {
    Frodo = {
        name = "Frodo Baggins",
        team = "blue"
    },
    Boromir = {
        score = 5
    }
}
local someOtherInfo = {
    Frodo = {
        team = "red",
        score = 10
    },
    Bilbo = {
        team = "yellow",

    },
    Boromir = {
        score = {1, 2, 3}
    }
}
local assignedInfo = dash.assign(someInfo, someOtherInfo)
--[[
    --> {
        Frodo = {
            name = "Frodo Baggins",
            team = "blue"
        },
        Boromir = {
            score = 5
        }
        Bilbo = {
            team = "yellow"
        }
    }
]]

See


defaultSerializer

function dash.defaultSerializer(input) --> string
A function which provides a simple, shallow string representation of a value.

Type

any -> string

Parameters

input - any - any value

Returns

string - a string

Examples

dash.defaultSerializer() --> "nil"
dash.defaultSerializer(true) --> "true"
dash.defaultSerializer(5.8) --> "5.8"
dash.defaultSerializer("Hello " .. \n .. " there") --> '"Hello \n there"'

entries

function dash.entries(source) --> {K, V}[]
Returns an array of all the entries of elements in source.

Each entry is a tuple (key, value).

Type

<T: Iterable<K,V>>(T -> {K, V}[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

{K, V}[] - an array (of arrays (of tuples (the primary key type and the primary value type)))

Examples

dash.values({
Frodo = 1,
Boromir = 2,
Bilbo = 3
}) --> {{"Frodo", 1}, {"Boromir", 2}, {"Bilbo", 3}} (in some order)

filter

function dash.filter(source, handler) --> V[]
Returns an array of any values in source that the handler function returned true for, in order of iteration.

Type

<T: Iterable<K,V>>(T, (element: V, key: K -> bool) -> V[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

handler - (element: V, key: K) -> bool - a function (taking element (the primary value type) and key (the primary key type), and returning a boolean)

Returns

V[] - an array (of the primary value type)

Examples

local myTools = game.Players.LocalPlayer.Backpack:GetChildren()
local mySpoons = dash.filter(myTools, function(tool)
    return dash.endsWith(tool.Name, "Spoon")
end)
mySpoons --> {SilverSpoon, TableSpoon}

See

  • dash.map if you would like to remove elements but preserve table keys

find

function dash.find(source, handler) --> V?
Picks a value from the table that handler returns true for.

If multiple elements might return true, any one of them may be returned as the iteration order over a table is stochastic.

Type

<T: Iterable<K,V>>((T, (element: V, key: K) -> bool) -> V?)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - (T, element: V, key: K) -> bool - a function (taking the primary type and a tuple (element (the primary value type) and key (the primary key type)), and returning a boolean)

handler - any - any value

Returns

V? - the primary value type (optional)

Examples

local names = {
    [3] = "Boromir",
    [1] = "Frodo",
    [8] = "Bilbo"
}
local nameWithB = dash.find(names, function(name)
    return dash.startsWith(name, "B")
end)
nameWithB --> "Bilbo", 8 (or "Boromir", 3)

-- Or use a chain:
local nameWithF = dash.find(names, dash.fn:startsWith(name, "B"))
nameWithF --> "Frodo", 1

-- Or find the key of a specific value:
local _, key = dash.find(names, dash.fn:matches("Bilbo"))
key --> 8

Usage

  • If you need to find the first value of an array that matches, use dash.first.

See


flatMap

function dash.flatMap(source, handler) --> V2[]
Like dash.mapValues this function iterates through source and returns an array of values, using handler to transform them. However, handler must return an array of results, these elements being insterted into the resulting array.

You can return an empty array {} from handler to avoid inserting anything for a particular element.

Type

<T: Iterable<K,V>, V2>((T, (element: V, key: K) -> V2[]) -> V2[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

V2 - any - the secondary value type (extends any value)

Parameters

source - (T, element: V, key: K) -> V2[] - a function (taking the primary type and a tuple (element (the primary value type) and key (the primary key type)), and returning an array (of the secondary value type))

handler - any - any value

Returns

V2[] - an array (of the secondary value type)

Examples

local tools = dash.flatMap(game.Players:GetPlayers(), function(player)
    return player.Backpack:GetChildren()
end)
tools --> {Spoon, Ring, Sting, Book}

Chainable

get

function dash.get(source, ...) --> V?
Get a child or descendant of a table, returning nil if any errors are generated.

Type

<K, V, T: {[K]: V}>(T, ...K) -> V?

Generics

K - any - the primary key type (extends any value)

V - any - the primary value type (extends any value)

T - {[K]: V} - the primary type (extends a dictionary mapping the primary key type to the primary value type)

Parameters

source - T - the primary type

... - ...K - the primary key type - Further keys to address any descendent.

Returns

V? - the primary value type (optional)

Examples

local upperTorso = dash.get(game.Players, "LocalPlayer", "Character", "UpperTorso")
upperTorso --> Part (if player's character and its UpperTorso are defined)
-- You can also bind a lookup to get later on:
local getUpperTorso = dash.bindTail(dash.get, "Character", "UpperTorso")
getUpperTorso(players.LocalPlayer) --> Part

groupBy

function dash.groupBy(source, handler) --> Iterable<K2, Iterable<K, V>>
This function iterates over source, calling handler to obtain a key for each element. Elements from source are then appended to an array of elements based on their key, so that this function returns a dictionary of arrays of the elements grouped by their keys.

If the handler returns nil, the element is dropped from the result.

Type

<T: Iterable<K,V>, K2>(((value: T, key: K) -> K2) -> Iterable<K2, Iterable<K,V>>)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

K2 - any - the secondary key type (extends any value)

Parameters

source - (value: T, key: K) -> K2 - a function (taking value (the primary type) and key (the primary key type), and returning the secondary key type)

handler - any - any value

Returns

Iterable<K2, Iterable<K, V>> - an Iterable (of the secondary key type and an Iterable (of the primary key type and the primary value type))

Examples

local playerSet = {Frodo = "Frodo", Bilbo = "Bilbo", Boromir = "Boromir"}
local healthSet = dash.keyBy(playerSet, function(name)
    return dash.get(game.Players, name, "Character", "Humanoid", "Health")
end)
healthSet --> {100 = {}, 50 = {"Bilbo", "Frodo"}, 0 = {"Boromir"}}

See


includes

function dash.includes(source, item) --> bool
Returns true if item exists as a value in the source table.

Type

<T: Iterable<K,V>>(T, V -> bool)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

item - V - the primary value type

Returns

bool - a boolean

Examples

local names = {
    [3] = "Boromir",
    [1] = "Frodo",
    [8] = "Bilbo"
}
dash.includes(names, "Boromir") --> true
dash.includes(names, 1) --> false

invert

function dash.invert(source) --> Iterable<V, K>
Returns a table with elements from source with their keys and values flipped.

Type

<K, V>(Iterable<K,V> -> Iterable<V,K>)

Generics

K - any - the primary key type (extends any value)

V - any - the primary value type (extends any value)

Parameters

source - Iterable<K, V> - an Iterable (of the primary key type and the primary value type)

Returns

Iterable<V, K> - an Iterable (of the primary value type and the primary key type)

Examples

local teams = {red = "Frodo", blue = "Bilbo", yellow = "Boromir"}
local players = dash.invert(teams)
players --> {Frodo = "red", Bilbo = "blue", Boromir = "yellow"}

isArray

function dash.isArray(source) --> bool
Returns true is source is made up only of natural keys 1..n.

Type

<T: Iterable<K,V>>(T -> bool)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

bool - a boolean

Examples

dash.isArray({1, 2, 3}) --> true
dash.isArray({a = 1, b = 2, c = 3}) --> false
-- Treating sparse arrays as natural arrays will only complicate things:
dash.isArray({1, 2, nil, nil, 3}) --> false
dash.isArray(dash.compact({1, 2, nil, nil, 3})) --> true

isEmpty

function dash.isEmpty(source) --> bool
Returns true if source has no keys.

Type

<T: Iterable<K,V>>(T -> bool)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

bool - a boolean

Examples

dash.isEmpty({}) --> true
dash.isEmpty({false}) --> false
dash.isEmpty({a = 1}) --> false

Usage

  • Note that a table only has a length if it is an array, so this can be used on non-arrays.

isSubset

function dash.isSubset(left, right) --> bool
Returns true if all the values in left match corresponding values in right recursively.

  • For elements which are not tables, they match if they are equal.
  • If they are tables they match if the right table is a subset of the left.

Type

<T>(T{}, T{}) -> bool

Generics

T - any - the primary type (extends any value)

Parameters

left - T{} - a dictionary (of the primary type)

right - T{} - a dictionary (of the primary type)

Returns

bool - a boolean

Examples

local car = {
    speed = 10,
    wheels = 4,
    lightsOn = {
        indicators = true,
        headlights = false
    }
}
dash.isSubset(car, {}) --> true
dash.isSubset(car, car) --> true
dash.isSubset(car, {speed = 10, lightsOn = {indicators = true}}) --> true
dash.isSubset(car, {speed = 12}) --> false
dash.isSubset({}, car) --> false

iterator

function dash.iterator(source, asArray) --> Iterator<T>
Determines a suitable Iterator to use for source, allowing source to be either a plain table, a table that has a metatable with an iterable key, or a function.

By default, the iterator is unordered, but passing asArray as true uses ipairs to iterate through natural keys 1..n in order.

Type

<T: Iterable>(T, bool -> Iterator<T>)

Generics

T - Iterable - the primary type (extends an Iterable)

Parameters

source - T - the primary type

asArray - bool - a boolean

Returns

Iterator<T> - an Iterator (of the primary type)


keyBy

function dash.keyBy(source, handler) --> Iterable<K2, V>
This function iterates over source, calling handler to obtain a key for each element. The element is then assigned by its key to the resulting object, overriding any previous element assigned to that key from source.

If the handler returns nil, the element is dropped from the result.

Type

<T: Iterable<K,V>, K2>((T, (element: V, key: K) -> K2) -> Iterable<K2,V>)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

K2 - any - the secondary key type (extends any value)

Parameters

source - (T, element: V, key: K) -> K2 - a function (taking the primary type and a tuple (element (the primary value type) and key (the primary key type)), and returning the secondary key type)

handler - any - any value

Returns

Iterable<K2, V> - an Iterable (of the secondary key type and the primary value type)

Examples

local playerSet = {Frodo = true, Bilbo = true, Boromir = true}
local healthSet = dash.keyBy(playerSet, function(name)
    return dash.get(game.Players, name, "Character", "Humanoid", "Health")
end)
healthSet --> {100 = true, 50 = true, 0 = true}

See

  • dash.groupBy - if you want to preseve all the elements at each key.

keys

function dash.keys(source) --> K[]
Returns an array of all the keys of the elements in source.

Type

<T: Iterable<K,V>>(T -> K[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

K[] - an array (of the primary key type)

Examples

dash.values({
    Frodo = 1,
    Boromir = 2,
    Bilbo = 3
}) --> {"Frodo", "Boromir", "Bilbo"} (in some order)

len

function dash.len(source) --> int
Returns the number of elements in source.

Type

<T: Iterable<K,V>>(T -> int)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

int - an integer

Examples

local names = {
    [3] = "Boromir",
    [1] = "Frodo",
    [8] = "Bilbo"
}
dash.len(names) --> 3

Usage

  • Note that a table only has a length if it is an array, so this can be used on non-arrays.

map

function dash.map(source, handler) --> Iterable<K, V2>
Create a new table from source where each value is replaced with the value returned from calling handler with each element in source.

Type

<T: Iterable<K,V>, V2>((T, (element: V, key: K) -> V2) -> Iterable<K,V2>)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

V2 - any - the secondary value type (extends any value)

Parameters

source - (T, element: V, key: K) -> V2 - a function (taking the primary type and a tuple (element (the primary value type) and key (the primary key type)), and returning the secondary value type)

handler - any - any value

Returns

Iterable<K, V2> - an Iterable (of the primary key type and the secondary value type)

Examples

-- Use map to get the same property of each value:
local playerNames = dash.map(game.Players:GetPlayers(), function(player)
    return player.Name
end)
playerNames --> {"Frodo Baggins", "Bilbo Baggins", "Boromir"}
-- Use map to remove elements while preserving keys:
local ingredients = {veg = "carrot", sauce = "tomato", herb = "basil"}
local carrotsAndHerbs = dash.map(ingredients, function(value, key)
    if value == "carrot" or key == "herb" then
        return value
    end
end)
carrotsAndHerbs --> {veg = "carrot", herb = "basil"}
-- Use map with multiple values of a table at once:
local numbers = {1, 1, 2, 3, 5} 
local nextNumbers = dash.map(numbers, function(value, key)
    return value + (numbers[key - 1] or 0)
end)
nextNumbers --> {1, 2, 3, 5, 8}

See

  • dash.filter - if you want to remove values using a predicate.

mapValues

function dash.mapValues(source, handler) --> V2[]
Like dash.map, but returns an array of the transformed values in the order that they are iterated over, dropping the original keys.

Type

<T: Iterable<K,V>, V2>((T, (element: V, key: K) -> V2) -> V2[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

V2 - any - the secondary value type (extends any value)

Parameters

source - (T, element: V, key: K) -> V2 - a function (taking the primary type and a tuple (element (the primary value type) and key (the primary key type)), and returning the secondary value type)

handler - any - any value

Returns

V2[] - an array (of the secondary value type)

Examples

local ingredients = {veg = "carrot", sauce = "tomato", herb = "basil"}
local list = dash.mapValues(function(value)
    return dash.format("{} x2", value)
end)
list --> {"carrot x2", "tomato x2", "basil x2"} (in some order)

Usage

  • This is equivalent to dash.values(dash.map(...)) but more concise.

See


merge

function dash.merge(target, ...) --> T
Mutates target by iterating recursively through elements of the subsequent arguments in order and inserting or replacing the values in target with each element preserving keys.

If any values are both tables, these are merged recursively using dash.merge.

Type

<T: Iterable<K,V>>(mut T, ...T) -> T

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

target - mut T - the primary type (which can be mutated)

... - ...T - the primary type

Returns

T - the primary type

Examples

local someInfo = {
    Frodo = {
        name = "Frodo Baggins",
        team = "blue"
    },
    Boromir = {
        score = 5
    }
}
local someOtherInfo = {
    Frodo = {
        team = "red",
        score = 10
    },
    Bilbo = {
        team = "yellow",

    },
    Boromir = {
        score = {1, 2, 3}
    }
}
local mergedInfo = dash.merge(someInfo, someOtherInfo)
--[[
    --> {
        Frodo = {
            name = "Frodo Baggins",
            team = "red",
            score = 10
        },
        Bilbo = {
            team = "yellow"
        },
        Boromir = {
            score = {1, 2, 3}
        }
    }
]]

See


occurences

function dash.occurences(source) --> {[T]: int}
Return a set of the tables that appear as descendants of source, mapped to the number of times each table has been found with a unique parent.

Repeat occurences are not traversed, so the function is cycle-safe. If any tables in the result have a count of two or more, they may form cycles in the source.

Type

<T: Iterable<K,V>>(T -> {[T]:int})

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

{[T]: int} - a dictionary mapping the primary type to integers

Examples

local plate = {veg = "potato", pie = {"stilton", "beef"}}
dash.occurences(plate) --[[> {
    [{veg = "potato", pie = {"stilton", "beef"}}] = 1
    [{"stilton", "beef"}] = 1
}]]
local kyle = {name = "Kyle"}
kyle.child = kyle
dash.occurences(kyle) --[[> {
    [{name = "Kyle", child = kyle}] = 2
}]]

one

function dash.one(source) --> V, K?
Returns an element from source, if it has one.

If there are multiple elements in source, any one of them may be returned as the iteration order over a table is stochastic.

Type

<T: Iterable<K,V>>(T -> (V, K)?)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

V, K? - a tuple (the primary value type and the primary key type) (optional)

Examples

dash.one({}) --> nil
dash.one({a = 1, b = 2, c = 3}) --> b, 2 (or any another element)

privatize

function dash.privatize(source) --> T{}
Returns a copy of source, ensuring each key starts with an underscore _.

Keys which are already prefixed with an underscore are left unchanged.

Type

<T>(T{} -> T{})

Generics

T - any - the primary type (extends any value)

Parameters

source - T{} - a dictionary (of the primary type)

Returns

T{} - a dictionary (of the primary type)

Examples

local privates = dash.privatize({
    [1] = 1,
    public = 2,
    _private = 3
})
privates --> {_1 = 1, _public = 2, _private = 3}
-- Make a static factory to create Cars with private fields
local interface = {
    speed = t.number,
    color = t.string
}
local Car = dash.classWithInterface(
    dash.privatize(interface)
)
local CarFactory = {
    make = function(props)
        return Car.new(dash.privatize(props))
    end
}
-- Create a new car using a public interface:
local car = CarFactory.make({
    speed = 5,
    color = 'red'
})
-- By convention, private fields should only by their owner.
car._speed --> 5

Usage

  • Fields starting with an underscore are considered private in many programming languages without inbuild access control. This function allows you to translate a public interface into a private one suitable for a class instance with private fields.

See


serialize

function dash.serialize(source, options) --> string
Returns a string representation of source including all elements with sorted keys.

dash.serialize preserves the properties of being unique, stable and cycle-safe if the serializer functions provided also obey these properties.

Type

<T: Iterable<K,V>>((T, SerializeOptions<T>) -> string)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

options - SerializeOptions<T> - a SerializeOptions (of the primary type)

Returns

string - a string

Examples

dash.serialize({1, 2, 3}) --> "{1,2,3}"
dash.serialize({a = 1, b = true, [3] = "hello"}) --> '{"a":1,"b":true,3:"hello"}'
dash.serialize({a = function() end, b = {a = "table"})
--> '{"a":<function: 0x...>,"b"=<table: 0x...>}'

Usage

  • Use dash.serialize when you need a representation of a table which doesn't need to be human-readable, or you need to customize the way serialization works. dash.pretty is more appropriate when you need a human-readable string.

See


serializeDeep

function dash.serializeDeep(source, options) --> string
Like dash.serialize, but if a child element is a table it is serialized recursively.

Returns a string representation of source including all elements with sorted keys.

This function preserves uniqueness, stability and cycle-safety.

Type

<T: Iterable<K,V>>((T, SerializeOptions<T>) -> string)

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

options - SerializeOptions<T> - a SerializeOptions (of the primary type)

Returns

string - a string

Examples

dash.serializeDeep({a = {b = "table"}) --> '{"a":{"b":"table"}}'
local kyle = {name = "Kyle"}
kyle.child = kyle
dash.serializeDeep(kyle) --> '<0>{"child":<&0>,"name":"Kyle"}'

See


Chainable

set

function dash.set(source, path, value) --> bool
Set a child or descendant value in a table. Returns true if the operation completed without error.

The function walks through the object using keys from path in turn. If any values along the path are not tables, dash.set will do nothing and return false.

Type

<T: Iterable<K, V>>(T, K[], V) -> bool

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

path - K[] - an array (of the primary key type)

value - V - the primary value type

Returns

bool - a boolean - true if the set worked

Examples

dash.set(game.Players, {"LocalPlayer", "Character", "UpperTorso", "Color"}, Color3.new(255, 255, 255))
--> true (if the set worked)

shallowEqual

function dash.shallowEqual(left, right) --> bool
Returns true if left and right are equal, or if they are tables and the elements in one are present and have equal values to those in the other.

Type

any, any -> bool

Parameters

left - any - any value

right - any - any value

Returns

bool - a boolean

Examples

local car = {
    speed = 10,
    wheels = 4,
    lightsOn = {
        indicators = true,
        headlights = false
    }
}
dash.shallowEqual(car, {}) --> false
dash.shallowEqual(car, car) --> true
dash.shallowEqual(car, dash.clone(car)) --> true
dash.shallowEqual(car, dash.cloneDeep(car)) --> false

Based on https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/update/using_should_component_update.html

See


unique

function dash.unique(source) --> T[]
Returns an array of the values in source, without any repetitions.

Values are considered equal if the have the same key representation.

Type

<T>(T[] -> T[])

Generics

T - any - the primary type (extends any value)

Parameters

source - T[] - an array (of the primary type)

Returns

T[] - an array (of the primary type)

Examples

local list = {1, 2, 2, 3, 5, 1}
dash.unique(list) --> {1, 2, 3, 5} (or another order)

values

function dash.values(source) --> V[]
Returns an array of all the values of the elements in source.

Type

<T: Iterable<K,V>>(T -> V[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

Returns

V[] - an array (of the primary value type)

Examples

dash.values({
    Frodo = 1,
    Boromir = 2,
    Bilbo = 3
}) --> {1, 2, 3} (in some order)

without

function dash.without(source, value) --> V[]
Returns an array of elements in source with any elements of value removed.

Type

<T: Iterable<K,V>>(T, V -> V[])

Generics

T - Iterable<K, V> - the primary type (extends an Iterable (of the primary key type and the primary value type))

Parameters

source - T - the primary type

value - V - the primary value type

Returns

V[] - an array (of the primary value type)

Examples

local points = {0, 10, 3, 0, 5}
local nonZero = dash.without(points, 0)
nonZero --> {10, 3, 5}
local ingredients = {veg = "carrot", sauce = "tomato", herb = "basil"}
local withoutCarrots = dash.without(ingredients, "carrot")
withoutCarrots --> {"tomato", "basil"} (in some order)