Reactivity: Tables
When should I use indexes, keys, and values?
valuesshould be used when you're dealing with an array or a dictionary where the key does not matter, and you want to manipulate values.indexesshould be used when you're dealing with an array or a dictionary with non-duplicate values, and you want to rearrange the positions of each value. Some good usecases are:- Creating a list of all players
- Displaying a history of chat messages
- Toast notifications
keyscan be used for dictionaries, arrays, and especially sets (where the keys can be anything and the values are all set totrue, or some other constant).
values()
Transforms the values of your state.
type Map<K, V> = { [K]: V }
type Cleanup = () -> ()
type Molecule<T> = () -> T
type Derivable<T> = (Molecule<T>) | T
type MapMolecule<K, V> = Molecule<Map<K, V>>
function values<K0, V0, V1>(
state: Derivable<Map<K0, V0>>,
mapper: (Molecule<V0>, K0) -> V1
): MapMolecule<K0, V1>Parameters
state: A derivable that represents a dictionary or an array that you want to map over.mapper: A function that is called for each key and value in yourstate. The mapper can return a value.
Returns
values returns a read-only flec.
Implementation details
- For keys that are added to
state, a stable scope is created once to schedule cleanup functions, and themapperfunction gets called and returns the new value.- If the value returned from the
mapperfunction is an Instance, it will be cached until the original key is removed.
- If the value returned from the
- For keys that are removed from
state, the stable scope is destroyed. - Any time an existing key's value changes:
- If the
mapperinitially returned an Instance, only the molecule (the first argument in themappercallback) will update with the new value. - If the
mapperinitially returned a non-Instance (tables, strings, numbers, etc.),mapperwill be called with the updated molecule (the first argument in themappercallback).
- If the
Examples:
local test = flec({ 1, 2, 3 })
local double = values(test, function(number, _index)
return number() * 2
end)
print(double()) --> { 2, 4, 6 }local source = { "i'm the strongest there is!" }
local all_uppercase = values(source, function(value)
return string.upper(value())
end)
print(all_uppercase()) --> { "I'M THE STRONGEST THERE IS!" }type Item = { name: string, description: string }
local function item_display(item: () -> Item, i: number)
local item_desc = computed(function()
local data = item()
return data.description
end)
local item_name = computed(function()
local data = item()
return data.name
end)
return new "TextLabel" {
Text = item_desc,
Name = function()
return `{i}: {item_name()}`
end,
}
end
local items = flec({} :: { Item })
local item_displays = values(items, function(item, i)
return item_display(item, i)
end)indexes()
Transforms the values of your state.
type Map<K, V> = { [K]: V }
type Cleanup = () -> ()
type Molecule<T> = () -> T
type Derivable<T> = (Molecule<T>) | T
type MapMolecule<K, V> = Molecule<Map<K, V>>
function indexes<K0, V0, V1>(
state: Derivable<Map<K0, V0>>,
mapper: (V0, Molecule<K0>) -> V1
): MapMolecule<K0, V1>Duplicate values
Having the same values appear multiple times in the input flec table can cause unexpected behavior. Teisu.strict, if enabled, can check for duplicate values and can let you know right away.
Parameters
state: A derivable that represents a dictionary or an array that you want to map over.mapper: A function that is called for each key and value in yourstate. The mapper can return a value.
Returns
indexes returns a read-only flec.
Implementation details
- For indexes that are added to
state, a stable scope is created once to schedule cleanup functions, and themapperfunction gets called and returns the new value.- If the value returned from the
mapperfunction is an Instance, it will be cached until the original key is removed.
- If the value returned from the
- For indexes that are removed from
state, the stable scope is destroyed. - Any time an existing value's index changes:
- If the
mapperinitially returned an Instance, only the molecule (the second argument in themappercallback) will update with the new index. - If the
mapperinitially returned a non-Instance (tables, strings, numbers, etc.),mapperwill be called with the updated molecule (the second argument in themappercallback).
- If the
Examples:
local todos = flec({ "go shopping", "eat food", "head back home" })
local numbered_todos = indexes(todos, function(value, index)
return `{index()}. {value}`
end)type Item = { name: string, description: string }
local function item_display(item: Item, i: () -> number)
return new "TextLabel" {
Text = item.description,
Name = function()
return `{i()}: {item.Name}`
end,
}
end
local items = flec({} :: { Item })
local item_displays = indexes(items, function(item, i)
return item_display(item, i)
end)keys()
Transforms the keys of your state.
type Map<K, V> = { [K]: V }
type Cleanup = () -> ()
type Molecule<T> = () -> T
type Derivable<T> = (Molecule<T>) | T
type MapMolecule<K, V> = Molecule<Map<K, V>>
function keys<K0, V0, V1>(
state: Derivable<Map<K0, V0>>,
mapper: (V0, K0) -> K1
): MapMolecule<K1, V0>Parameters
state: A derivable that represents a dictionary, set or an array that you want to map over.mapper: A function that is called for each key in yourstate. The mapper can return a key.
Returns
keys returns a read-only flec.
Example:
local data = flec({ foo = "bar", bar = "bazz" })
local uppercase = keys(data, function(key)
return string.upper(key)
end)
print(uppercase()) --> { FOO = "bar", BAR = "bazz" }