--!native -- Compiled with roblox-ts v3.0.0 local TS = _G[script] local ArrayTools = TS.import(script, script.Parent, "array_tools").ArrayTools --[[ * * If the lib "ES2015.Collection" is not included in tsconfig.json, * types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere) * or `{}` (from the node types), in both cases entering an infinite recursion in * pattern matching type mappings * This type can be used to cast these types to `void` in these cases. ]] --[[ * * These should also never be mapped but must be tested after regular Map and * Set ]] --*@alias Draft in rbxts/immut local TableTools local TableTools = {} do local _container = TableTools --[[ * * clones the immutable data and executes the function with draft as argument * @param data data to be cloned * @param callback draft is a clone of the data with readonly flag removed * @returns new changed copy of data (draft) ]] local function CopyData(data, callback) --clones the data local clone = table.clone(data) callback(clone) return clone end _container.CopyData = CopyData local IsArray local function DeepCopyData(data, callback) --clones the data local clone = table.clone(data) if IsArray(clone) then --type is already array local cloned_table = clone -- ▼ ReadonlyArray.forEach ▼ local _callback = function(value, index) local _value = value clone[index + 1] = if type(_value) == "table" then DeepCopyData(value) else value end for _k, _v in cloned_table do _callback(_v, _k - 1, cloned_table) end -- ▲ ReadonlyArray.forEach ▲ else --type is already array local cloned_table = clone -- ▼ ReadonlyMap.forEach ▼ local _callback = function(value, key) local _exp = key local _value = value local _arg1 = if type(_value) == "table" then DeepCopyData(value) else value cloned_table[_exp] = _arg1 end for _k, _v in cloned_table do _callback(_v, _k, cloned_table) end -- ▲ ReadonlyMap.forEach ▲ end if callback then callback(clone) end return clone end _container.DeepCopyData = DeepCopyData local function FillOutDefaults(data, default_data) local _object = table.clone(default_data) setmetatable(_object, nil) for _k, _v in data do _object[_k] = _v end return _object end _container.FillOutDefaults = FillOutDefaults --*returns the keys of the map local function GetKeys(map) local keys = {} for key, _ in map do table.insert(keys, key) end return keys end _container.GetKeys = GetKeys --*returns the values of the map local function GetValues(map) local values = {} for _, value in map do table.insert(values, value) end return values end _container.GetValues = GetValues function IsArray(data) -- ▼ ReadonlyMap.size ▼ local _size = 0 for _ in data do _size += 1 end -- ▲ ReadonlyMap.size ▲ return _size == #data end _container.IsArray = IsArray local function ExtractElementsFromRecursiveData(data, check, ignore_table_if_added) if ignore_table_if_added == nil then ignore_table_if_added = true end local taken_elements = {} local array = data local ExtractElements local CheckElement = function(key, element) local _element = element local is_table = type(_element) == "table" local should_be_added = check(element, key, taken_elements, data) if should_be_added then local _element_1 = element table.insert(taken_elements, _element_1) end --ignore the table if it was added if is_table and should_be_added and ignore_table_if_added then return nil end --extracts elements from the table recursively if is_table then ExtractElements(element) end end ExtractElements = function(array) for key, element in array do CheckElement(key, element) end end ExtractElements(array) return taken_elements end _container.ExtractElementsFromRecursiveData = ExtractElementsFromRecursiveData local function Filter(map, check) local filtered_map = {} for key, value in map do if check(value, key, map) then filtered_map[key] = value end end return filtered_map end _container.Filter = Filter --*@returns first element from the map [key, value] local function GetFirst(map) for key, value in map do return key, value end end _container.GetFirst = GetFirst local function GetRandomKey(map) return ArrayTools.GetRandomElement(TableTools.GetKeys(map)) end _container.GetRandomKey = GetRandomKey local function GetRandomValue(map) return ArrayTools.GetRandomElement(TableTools.GetValues(map)) end _container.GetRandomValue = GetRandomValue local function GetOrCreate(map, key, create_callback) local _map = map local _key = key local _condition = _map[_key] if _condition == nil then local _map_1 = map local _key_1 = key local _arg1 = create_callback(key, map) _map_1[_key_1] = _arg1 local _key_2 = key _condition = _map_1[_key_2] end return _condition end _container.GetOrCreate = GetOrCreate local function Find(map, check) for key, value in map do if check(value, key, map) then return value end end end _container.Find = Find local function FindKey(map, check) for key, value in map do if check(value, key, map) then return key end end end _container.FindKey = FindKey local function Includes(map, check) for key, value in map do if check(value, key, map) then return true end end return false end _container.Includes = Includes local function KeyOf(map, seached_value) for key, value in map do if seached_value == value then return key end end end _container.KeyOf = KeyOf local function ToPairs(map) local key_value_pairs = {} for k, v in map do local _arg0 = { k, v } table.insert(key_value_pairs, _arg0) end return key_value_pairs end _container.ToPairs = ToPairs local function MapToArray(map, selector) local array = {} for key, value in map do local selected_value = selector(key, value, map) table.insert(array, selected_value) end return array end _container.MapToArray = MapToArray local function MapToArrayFiltered(map, selector) local array = {} for key, value in map do local selected_value = selector(key, value, map) if selected_value == nil then continue end table.insert(array, selected_value) end return array end _container.MapToArrayFiltered = MapToArrayFiltered --[[ * * * @param new_map * @param old_map * @returns keys that dont exist in new_map, but exist in old_map ]] local function GetMissingKeys(new_map, old_map) local missing_keys = {} for old_key in old_map do if not (new_map[old_key] ~= nil) then table.insert(missing_keys, old_key) end end return missing_keys end _container.GetMissingKeys = GetMissingKeys --[[ * * * @param new_map * @param old_map * @returns keys that exist in new_map, but dont exist in old_map ]] local function GetNewKeys(new_map, old_map) local new_keys = {} for new_key in new_map do if not (old_map[new_key] ~= nil) then table.insert(new_keys, new_key) end end return new_keys end _container.GetNewKeys = GetNewKeys --[[ * * * @param new_map * @param old_map * @param selector * @param ignore_missing_or_new_keys * @returns keys of different values ]] local function GetDifferentValueKeys(new_map, old_map, selector, ignore_missing_or_new_keys) if ignore_missing_or_new_keys == nil then ignore_missing_or_new_keys = false end local different_keys = {} for new_key, value in new_map do local old_value = old_map[new_key] if old_value == nil and ignore_missing_or_new_keys then continue end --new keys if old_value == nil then table.insert(different_keys, new_key) continue end local are_same if selector == nil then are_same = value == old_value else are_same = selector(value, old_value, new_key, new_key, new_map, old_map) end if are_same then continue end table.insert(different_keys, new_key) end --missing keys if not ignore_missing_or_new_keys then for old_key in old_map do if not (new_map[old_key] ~= nil) then table.insert(different_keys, old_key) end end end return different_keys end _container.GetDifferentValueKeys = GetDifferentValueKeys --[[ * * maps the map to the new map * @param map map * @param selector => [new_key, new_value] * @returns mapped map from map ]] local function MapToNew(map, selector) local output = {} for key_0, value_0 in map do local _binding = selector(key_0, value_0, map) local key_1 = _binding[1] local value_1 = _binding[2] output[key_1] = value_1 end return output end _container.MapToNew = MapToNew --[[ * * maps the map to the new map, if no value was returned will filter the value * @param map map * @param selector => [new_key, new_value] * @returns mapped filtered map from map ]] local function MapFiltered(map, selector) local output = {} for key_0, value_0 in map do local selector_output = selector(key_0, value_0, map) if selector_output == nil then continue end local _arg0 = selector_output[1] local _arg1 = selector_output[2] output[_arg0] = _arg1 end return output end _container.MapFiltered = MapFiltered end return { TableTools = TableTools, }