--!native --!optimize 2 -- Compiled with roblox-ts v3.0.0 local ArrayTools = {} do local _container = ArrayTools local random = Random.new() --[[ * * * @param array * @returns shuffled copy of array * @deprecated use new Random().Shuffle() instead ]] local function Shuffle(array) local array_size = #array local shuffled_array = table.create(array_size) --goes backwards to avoid conflict with randomised numbers; --takes the random index and swaps with the current for i = array_size - 1, 0, -1 or 1 do local random_index = random:NextInteger(0, i) local random_value = array[random_index + 1] --if value in shuffled array exist, dont take from the existing array --can cause duplicats local _condition = shuffled_array[i + 1] if _condition == nil then _condition = array[i + 1] end local current_value = _condition --swaps the values current with random; shuffled_array[i + 1] = random_value shuffled_array[random_index + 1] = current_value end return shuffled_array end _container.Shuffle = Shuffle --*removes the element from the array local function RemoveElementFromArray(array, element) local _array = array local _array_1 = array local _element = element local _arg0 = (table.find(_array_1, _element) or 0) - 1 return table.remove(_array, _arg0 + 1) end _container.RemoveElementFromArray = RemoveElementFromArray --[[ *removes all or 1 elements if they check function returns true * @param [stop_on_first=true] * @returns removed elements ]] local function RemoveFromArray(array, check, stop_on_first) if stop_on_first == nil then stop_on_first = true end local indexes_to_remove = {} for i = 0, #array - 1 do local element = array[i + 1] if not check(element) then continue end table.insert(indexes_to_remove, i) --stops if stop_on_first flag is true if stop_on_first then break end end local removed_elements = table.create(#indexes_to_remove) --goest backwards to not mess the indexes for i = #indexes_to_remove - 1, 0, -1 or 1 do local index_to_remove = indexes_to_remove[i + 1] local _arg0 = table.remove(array, index_to_remove + 1) table.insert(removed_elements, _arg0) end return removed_elements end _container.RemoveFromArray = RemoveFromArray local function IncludesOneOf(array, possible_elements) for _, element in possible_elements do if table.find(array, element) ~= nil then return true end end return false end _container.IncludesOneOf = IncludesOneOf --*@returns same elements in the arrays local function GetIntersection(array_0, array_1) local intersections = {} --if the element is in both tables any table could be used for _, element in array_0 do if table.find(array_1, element) ~= nil then table.insert(intersections, element) end end return intersections end _container.GetIntersection = GetIntersection --[[ *if insert_check returns true, element will be inserted at index of value that it's getting compared to * @param a - inserted value * @param b - other value ]] local function SortedInsert(array, value, insert_check) for i = 0, #array - 1 do if not insert_check(value, array[i + 1], i, array) then continue end local _array = array local _value = value table.insert(_array, i + 1, _value) return nil end local _array = array local _value = value table.insert(_array, _value) end _container.SortedInsert = SortedInsert --[[ * * interts elements at position * @param array * @param elements * @param position ]] local function InsertElements(array, elements, position) if position == nil then position = #array end for _, element in elements do local _array = array local _original = position position += 1 table.insert(_array, _original + 1, element) end return array end _container.InsertElements = InsertElements --*pushes element to the array if it doesnt exist local function PushIfDoesntExist(array, element) local _array = array local _element = element if table.find(_array, _element) ~= nil then return nil end local _array_1 = array local _element_1 = element table.insert(_array_1, _element_1) end _container.PushIfDoesntExist = PushIfDoesntExist --[[ * * @param arrays * @returns array that contains all elements from arrays ]] local function JoinArrays(arrays) -- ▼ ReadonlyArray.reduce ▼ local _result = {} local _callback = function(combined_array, array) local _array = {} local _length = #_array local _combined_arrayLength = #combined_array table.move(combined_array, 1, _combined_arrayLength, _length + 1, _array) _length += _combined_arrayLength table.move(array, 1, #array, _length + 1, _array) return _array end for _i = 1, #arrays do _result = _callback(_result, arrays[_i], _i - 1, arrays) end -- ▲ ReadonlyArray.reduce ▲ return _result end _container.JoinArrays = JoinArrays local function GetRandomElement(array) --returns array element with random index local random_index = random:NextInteger(0, #array - 1) return array[random_index + 1] end _container.GetRandomElement = GetRandomElement local function WeightedPick(array) local total_value = 0 for _, element in array do local _binding = element local weight = _binding[1] local _ = _binding[2] total_value += weight end local random_value = random:NextNumber() * total_value for _, element in array do local _binding = element local weight = _binding[1] local value = _binding[2] if random_value < weight then return value end random_value -= weight end error("array doent contain any items") end _container.WeightedPick = WeightedPick --[[ *filters the same value, if selector is undefined will use the element itself to compare * overrides array and retuns it ]] local function FilterSame(array, selector) local indexes_to_remove = {} local found_values = {} for i = 0, #array - 1 do local element = array[i + 1] --uses selector to select the element or uses element itself local _result = selector if _result ~= nil then _result = _result(element) end local _condition = _result if _condition == nil then _condition = element end local value = _condition if table.find(found_values, value) ~= nil then --adds to the indexes in order to remove table.insert(indexes_to_remove, i) continue end table.insert(found_values, value) end --goes backwards to not mess up indexes for i = #indexes_to_remove - 1, 0, -1 or 1 do local index_to_remove = indexes_to_remove[i + 1] table.remove(array, index_to_remove + 1) end return array end _container.FilterSame = FilterSame --[[ * * * @param array * @param start * @param finish * @returns cut copy of array ]] local function SubArray(array, start, finish) local subtracted_array = {} local _array = array local _start = start local _finish = finish table.move(_array, _start + 1, _finish + 1, 1, subtracted_array) return subtracted_array end _container.SubArray = SubArray --[[ * * compares 2 array, returns true if they have same elements ]] local function Compare(array_0, array_1, selector) if #array_0 ~= #array_1 then return false end for i = 0, #array_0 - 1 do local _result = selector if _result ~= nil then _result = _result(array_0) end local _condition = _result if _condition == nil then _condition = array_0[i + 1] end local value_0 = _condition local _result_1 = selector if _result_1 ~= nil then _result_1 = _result_1(array_1) end local _condition_1 = _result_1 if _condition_1 == nil then _condition_1 = array_1[i + 1] end local value_1 = _condition_1 if value_0 ~= value_1 then return false end end return true end _container.Compare = Compare --[[ * * loops in the opposite direction * equivalent to for(let i = array.size() - 1; i >= 0, i--) ]] local function ReverseLoop(array, callback) for i = #array - 1, 0, -1 or 1 do local value = array[i + 1] callback(value, i, array) end end _container.ReverseLoop = ReverseLoop --*swaps elements in the table by indexes local function SwapIndexes(array, index_0, index_1) local _index = index_0 + 1 local _index_1 = index_1 + 1 array[_index], array[_index_1] = array[index_1 + 1], array[index_0 + 1] end _container.SwapIndexes = SwapIndexes --[[ * * @param array * @returns reversed copy of array ]] local function Reverse(array) local reversed_array = table.create(#array) ReverseLoop(array, function(value, index) local _value = value table.insert(reversed_array, _value) return #reversed_array end) return reversed_array end _container.Reverse = Reverse --[[ * * indexes the array and wraps the index * equivalent to array[index % array.size()] ]] local function WrapIndex(array, index) local size = #array return array[(if size ~= 0 then index % size else 0) + 1] end _container.WrapIndex = WrapIndex --[[ * * makes binary search in sorted array * @param array * @param element * @param return_min if didnt find the element and this is true, will return the index of the closes smallest element * @returns index of the element, -1 if didnt find the element ]] local function BinarySearch(array, element, return_min) local low = 0 local high = #array - 1 while low <= high do local mid = low + math.floor((high - low) / 2) if array[mid + 1] == element then return mid end if array[mid + 1] < element then low = mid + 1 else high = mid - 1 end end return if return_min then math.max(math.min(low, high), 0) else -1 end _container.BinarySearch = BinarySearch --[[ * * makes binary search in sorted array * @param array * @param element * @param return_min if didnt find the element and this is true, will return the index of the closes smallest element * @returns index of the element, -1 if didnt find the element ]] local function BinarySearchObject(array, element, selector, return_min) local low = 0 local high = #array - 1 while low <= high do local mid = low + math.floor((high - low) / 2) local middle_element = selector(array[mid + 1]) if middle_element == element then return mid end if middle_element < element then low = mid + 1 else high = mid - 1 end end return if return_min then math.max(math.min(low, high), 0) else -1 end _container.BinarySearchObject = BinarySearchObject local function CountElement(array, search_element, selector) local amount = 0 for _, element in array do local _result = selector if _result ~= nil then _result = _result(element) end local _condition = _result if _condition == nil then _condition = element end if _condition == search_element then amount += 1 end end return amount end _container.CountElement = CountElement --[[ * * splits array on arrays with fixed amount of components or less * @param array * @param amount_per_table * @returns ]] local function SplitArray(array, amount_per_table) if #array <= amount_per_table then return { array } end local amount_of_tables = math.ceil(#array / amount_per_table) local splitted_arrays = table.create(amount_of_tables) do local i = 0 local _shouldIncrement = false while true do if _shouldIncrement then i += 1 else _shouldIncrement = true end if not (i < amount_of_tables) then break end local _array = array local _arg0 = i * amount_per_table local _arg1 = (i + 1) * amount_per_table - 1 splitted_arrays[i + 1] = table.move(_array, _arg0 + 1, _arg1 + 1, 1, {}) end end return splitted_arrays end _container.SplitArray = SplitArray --[[ * * converts array to map * @param array array of elements to convert to the map * @param selector returns [key, value] for map * @returns map ]] local function ToMap(array, selector) local map = {} for i = 0, #array - 1 do local element = array[i + 1] local _binding = selector(element, i, array) local key = _binding[1] local value = _binding[2] map[key] = value end return map end _container.ToMap = ToMap end return { ArrayTools = ArrayTools, }