In this section, you will find multiple functions to work with arrays (or lists if you prefer).
In your code, it is encouraged to put this part of the library into a variable:
local Array = Disk.ArrayIf you are not familiar with this kind of utility functions, don't get overwhelmed and start with these:
Once you feel comfortable, you may want to take a look at these:
Verify if all elements in an array satisfy a certain condition expressed with a function.
As soon as one element does not satisfy the condition, the condition will not be verified for the rest of the elements.
-- result is true because the function will return true for ALL elements
local areAbove5 = Array.all({30, 6, 8, 10}, function(value: number)
return value > 5
end)
-- result is false because the function will return false for 6
local areAbove5 = Array.all({30, 6, 8, 10}, function(value: number)
return value > 7
end)
-- result is always true when the array is empty
local areAbove5 = Array.all({}, function(value: number)
return value > 5
end)Related: any
Creates a new array from multiple arrays, where the elements are taken one by one into each of the provided array.
local result = alternate({ 2, 4 }, { 'a', 'b' }) --> { 2, 'a', 4, 'b' }Verify that at least one element of the array satisfy a certain condition.
As soon as an element satisfies the condition, the condition will not be verified on the rest of the elements.
-- result is true because the function will return true for 8
local areAbove5 = Array.all({3, 7, 8, 3}, function(value: number)
return value == 8
end)
-- result is false because the function will return false for 6
local areAbove5 = Array.all({30, 6, 8, 10}, function(value: number)
return value > 7
end)
-- result is always false when the array is empty
local areAbove5 = Array.all({}, function(value: number)
return value > 5
end)Related: all
Calculates the average value from an array of numbers.
local result = Array.average({4, 6, 8, 8}) --> 6.5Related: averageBy
Calculates the average value of an array given a mapping function that produces numbers.
local result = Array.averageBy({"hello", " ", "world", "!"}, function(value)
return string.len(value)
end)
-- result is 4Related: average
Verifies if an array contains a certain value.
local result = Array.contains({"hello", "world", "!"}, "!")
-- result is trueRelated: find, findIndex, findIndexByValue, findMap
Takes multiple arrays and concat (chain) them into a single array.
local result = Array.concat({ 1, 2 }, { 3, 4 }) -- { 1, 2, 3, 4 }
local result = Array.concat({ "start" }, { 1, 3, 5 }, { "end" })
-- result = { "start", 1, 3, 5, "end" }Makes a shallow copy of an array.
local value = { 3, 4 }
local result = Array.copy(value)
print(value == result) -- false
print(value[1] == result[1] and value[2] == result[2]) -- trueCount the amount of elements that satisfy a predicate.
local array = { 'banana', 'cherry', 'date', 'blueberry' },
local result = count(array, function(value: string)
return #value > 5
end)
-- result is 3Removes duplicate elements from an array.
local result = Array.deduplicate({1, 2, 3, 2, 4, 5, 3}) --> {1, 2, 3, 4, 5}Related: deduplicateByKey
Removes duplicate elements from an array based on a mapping function. Instead of comparing each element with each other directly, they are compared using the value returned by the mapping function.
Note: the mapping function should never return nil.
local function getId(object)
return object.id
end
local result = Array.deduplicateByKey({
{ id = 1, value = 'a' },
{ id = 2, value = 'b' },
{ id = 1, value = 'c' }, -- this element is removed because it has the same id
}, getId)
-- result is { { id = 1, value = 'a' }, { id = 2, value = 'b' } }Related: deduplicate
Creates an array from only elements that satisfy a condition.
-- result is { 7, 9 }
local above5 = Array.filter({ 3, 7, 4, 9 }, function(element)
return element > 5
end)Related partition
Finds the first element in an array that satisfies a condition.
local result = Array.find({1, 2, 3, 4, 5}, function(value)
return value % 2 == 0
end)
-- result is 2Related: contains, findIndex, findIndexByValue, findMap, reverseFind
Finds the index of the first element in an array that satisfies a condition.
local result = Array.findIndex({1, 7, 16, 5}, function(value)
return value % 2 == 0
end)
-- result is 3Related: find, findIndexByValue, findMap, reverseFindIndex
Finds the index of the first occurrence of a value in an array.
local result = Array.findIndexByValue({ 'a', 'b', 'c', 'b', 'd' }, 'b')
-- result is 2Related: find, findIndex, findMap, reverseFindIndexByValue
Applies a mapping function to each element in an array and returns the first non-nil result.
local result = Array.findMap({ 'apple', 'banana', 'grape' }, function(fruit)
if string.len(fruit) > 5 then
return string.upper(fruit)
else
return nil
end
end)
-- result is 'BANANA'Related: find, findIndex, findIndexByValue, reverseFindMap
Maps each element of an array to a new array and then flattens the result into a single array.
local result = Array.flatMap({1, 2, 3}, function(value)
return {value, value * 2}
end)
-- result is {1, 2, 2, 4, 3, 6}Flattens a nested array structure into a single-level array. Optional depth determines the limit up to which the flattening should occur.
local result = Array.flatten({1, {2, {3, 4}}, 5})
-- result is {1, 2, {3, 4}, 5}
local deepNestedArray = {1, {2, {3, {4, 5}, 6}, 7}, 8}
local resultWithDepth = Array.flatten(deepNestedArray, 2)
-- resultWithDepth is {1, 2, 3, {4, 5}, 6, 7, 8}Related: flatMap
Generates an array by repeatedly applying a generating function.
local result = Array.fromFn(function(index)
if index > 5 then
return nil
end
return index * 2
end)
-- result is {2, 4, 6, 8, 10}Related: fromTryFn
Generates an array by repeatedly applying a generating function, safely handling errors. The function stops when the generator returns nil or throws an error.
local result = Array.fromTryFn(function(index)
if index > 5 then
return nil
end
return index * 2
end)
-- result is {2, 4, 6, 8, 10}
-- Stops on error
local result = Array.fromTryFn(function(index)
if index > 3 then
error('terminate')
end
return index
end)
-- result is {1, 2, 3}Related: fromFn
Inserts a value after the first element in an array that satisfies a condition. If no matching element is found, the original array is returned unchanged.
local result = Array.insertAfter({ 'a', 'b', 'c', 'd' }, 'x', function(x)
return x == 'b'
end)
-- result is { 'a', 'b', 'x', 'c', 'd' }
-- Returns original array when no match is found
local result = Array.insertAfter({ 'a', 'b', 'c' }, 'x', function(x)
return x == 'z'
end)
-- result is { 'a', 'b', 'c' }Optionally, a starting index can be provided to begin the search from a specific position.
local result = Array.insertAfter({ 'a', 'b', 'c', 'b', 'd' }, 'x', function(x)
return x == 'b'
end, 3)
-- result is { 'a', 'b', 'c', 'b', 'x', 'd' }Related: insertAfterIndex, insertBefore, insertBeforeIndex
Inserts a value after a specific index in an array. If the index is less than 1, the value is inserted at the beginning. If the index is greater than the array length, the value is appended to the end.
local result = Array.insertAfterIndex({ 'a', 'b', 'c', 'd' }, 'x', 2)
-- result is { 'a', 'b', 'x', 'c', 'd' }
-- Inserts at beginning when index < 1
local result = Array.insertAfterIndex({ 'a', 'b', 'c' }, 'x', 0)
-- result is { 'x', 'a', 'b', 'c' }
-- Appends to end when index > length
local result = Array.insertAfterIndex({ 'a', 'b', 'c' }, 'x', 10)
-- result is { 'a', 'b', 'c', 'x' }Related: insertAfter, insertBefore, insertBeforeIndex
Inserts a value before the first element in an array that satisfies a condition. If no matching element is found, the original array is returned unchanged.
local result = Array.insertBefore({ 'a', 'b', 'c', 'd' }, 'x', function(x)
return x == 'b'
end)
-- result is { 'a', 'x', 'b', 'c', 'd' }
-- Returns original array when no match is found
local result = Array.insertBefore({ 'a', 'b', 'c' }, 'x', function(x)
return x == 'z'
end)
-- result is { 'a', 'b', 'c' }Optionally, a starting index can be provided to begin the search from a specific position.
local result = Array.insertBefore({ 'a', 'b', 'c', 'b', 'd' }, 'x', function(x)
return x == 'b'
end, 3)
-- result is { 'a', 'b', 'c', 'x', 'b', 'd' }Related: insertAfter, insertAfterIndex, insertBeforeIndex
Inserts a value before a specific index in an array. If the index is less than 1, the value is inserted at the beginning. If the index is greater than the array length, the value is appended to the end.
local result = Array.insertBeforeIndex({ 'a', 'b', 'c', 'd' }, 'x', 2)
-- result is { 'a', 'x', 'b', 'c', 'd' }
-- Inserts at beginning when index < 1
local result = Array.insertBeforeIndex({ 'a', 'b', 'c' }, 'x', 0)
-- result is { 'x', 'a', 'b', 'c' }
-- Appends to end when index > length
local result = Array.insertBeforeIndex({ 'a', 'b', 'c' }, 'x', 10)
-- result is { 'a', 'b', 'c', 'x' }Related: insertAfter, insertAfterIndex, insertBefore
Given any value, returns true or false if it is an array.
local result = Array.isArray({ 'Bobby', 'Claudio' }) -- true
-- an array with different value types is still an array!
local result = Array.isArray({ 5, 'Claudio', false, function() end }) -- true
-- a dictionary is not an array!
local result = Array.isArray({ initialValue = 0 }) -- false
-- an empty table is an array
local result = Array.isArray({}) -- trueGiven an array, returns true if it has no elements.
local result = Array.isEmpty({}) -- true
local result = Array.isEmpty({ 10 }) -- falseCreates a new array by applying a function to each element in the array. If the function returns nil, it is skipped.
local squared = Array.map({1, 2, 3, 4}, function(value)
return value * value
end)
-- squared is {1, 4, 9, 16}Related flatMap
Given an array of number, returns the largest value of the array. An initial value has to be provided if the array is empty.
local result = Array.maximum({8, 6, 16, 4}) -- result is 16
-- the initial value may be return if it is the largest value
local result = Array.maximum({25, 5}, 100) -- result is 100Note: if the array is empty, the initial value will be returned.
Related maximumBy, minimum, minimumBy
Given an array and a mapping function that produces numbers, returns the largest value produced. An initial value has to be provided if the array is empty.
local result = Array.maximumBy({"hello", "bye", "good morning"}, function(value)
return string.len(value)
end)
-- result is 12Related maximum, minimum, minimumBy
Given an array of number, returns the smallest value of the array. An initial value has to be provided if the array is empty.
local result = Array.minimum({8, 6, 2, 4}, math.huge) -- result is 2
-- the initial value may be return if it is the smallest value
local result = Array.minimum({250, 500}, 10) -- result is 10Note: if the array is empty, the initial value will be returned.
Related minimumBy, maximum, maximumBy
Given an array and a mapping function that produces numbers, returns the smallest value produced. An initial value has to be provided if the array is empty.
local result = Array.minimumBy({"hello", "bye", "good morning"}, function(value)
return string.len(value)
end)
-- result is 12Related minimum, maximum, maximumBy
Splits an array into two arrays based on a condition.
local trueResults, falseResults = Array.partition({1, 2, 3, 4, 5}, function(value)
return value % 2 == 0
end)
-- trueResults is {2, 4}
-- falseResults is {1, 3, 5}Related filter
Remove one (or many) elements from the end of the array.
local result = Array.pop({1, 2, 3, 4, 5})
-- result is {1, 2, 3, 4}
local result2 = Array.pop({1, 2, 3, 4, 5}, 3)
-- result2 is {1, 2}Remove one (or many) elements from the start of the array.
local result = Array.popFirst({1, 2, 3, 4, 5})
-- result is {2, 3, 4, 5}
local result2 = Array.popFirst({1, 2, 3, 4, 5}, 3)
-- result2 is {4, 5}Calculate the product of an array of numbers.
local result = Array.product({2, 3, 4})
-- result is 24 (2 * 3 * 4)Calculates the product of an array given a mapping function that produces numbers.
local items = {{ value = 2 }, { value = 3 }, { value = 4 }}
local result = Array.productBy(items, function(item)
return item.value
end)
-- result is 24 (2 * 3 * 4)Add element(s) at the end of the array.
local array = {1, 2, 3}
local result = Array.push(array, 4, 5)
-- result is {1, 2, 3, 4, 5}Create a new array containing elements from the original array within the specified range.
local result = Array.range({'a', 'b', 'c', 'd', 'e', 'f'}, 2, 4)
-- result is {'b', 'c', 'd'}Applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
local result = Array.reduce({"a", "b", "c"}, function(acc, value)
acc[value] = true
return acc
end, {})
-- result is { a = true, b = true, c = true }Removes elements from an array based on their indexes.
local result = Array.removeIndexes({ 'a', 'b', 'c', 'd' }, { 4, 2 })
-- result is {'a', 'c'}Related removeSortedIndexes, removeValues
Removes elements using an array of indexes, but the array of indexes should be sorted.
local result = Array.removeSortedIndexes({ 'a', 'b', 'c', 'd' }, { 2, 4 })
-- result is {'a', 'c'}Related removeIndexes, removeValues
Removes specified values from an array.
local result = Array.removeValues({ 'a', 'b', 'c', 'd' }, 'b', 'd')
-- result is {'a', 'c'}Related removeIndexes, removeSortedIndexes
Replaces the value at a specific index in an array with a new value. Returns a new array with the replacement, or the original array if the index is out of bounds or if the replacement value equals the current value.
local result = Array.replaceAtIndex({ 1, 2, 3, 4 }, 2, 99)
-- result is { 1, 99, 3, 4 }
-- Returns original array when index is out of bounds
local original = { 1, 2, 3 }
local result = Array.replaceAtIndex(original, 10, 99)
-- result is the same array reference as original
-- Returns original array when replacement value equals current value
local original = { 1, 2, 3 }
local result = Array.replaceAtIndex(original, 2, 2)
-- result is the same array reference as originalCreate a new array but with the element in reverse order. For an array of less than 2 elements, this function will return the same array.
local result = Array.reversed({ 1, 2, 3 }) --> { 3, 2, 1 }Finds the last element in an array that satisfies a condition, searching from the end.
local result = Array.reverseFind({1, 2, 3, 4, 5}, function(value)
return value % 2 == 0
end)
-- result is 4Optionally, a starting index can be provided to begin the search from a specific position.
local result = Array.reverseFind({1, 2, 3, 4, 5}, function(value)
return value % 2 == 0
end, 3)
-- result is 2Related: find, reverseFindIndex, reverseFindIndexByValue, reverseFindMap
Finds the index of the last element in an array that satisfies a condition, searching from the end.
local result = Array.reverseFindIndex({1, 2, 3, 4, 5}, function(value)
return value % 2 == 0
end)
-- result is 4Optionally, a starting index can be provided to begin the search from a specific position.
local result = Array.reverseFindIndex({1, 2, 3, 4, 5}, function(value)
return value % 2 == 0
end, 3)
-- result is 2Related: findIndex, reverseFind, reverseFindIndexByValue, reverseFindMap
Finds the index of the last occurrence of a value in an array, searching from the end.
local result = Array.reverseFindIndexByValue({ 'a', 'b', 'c', 'b', 'd' }, 'b')
-- result is 4Optionally, a starting index can be provided to begin the search from a specific position.
local result = Array.reverseFindIndexByValue({ 'a', 'b', 'c', 'b', 'd' }, 'b', 3)
-- result is 2Related: findIndexByValue, reverseFind, reverseFindIndex, reverseFindMap
Applies a mapping function to each element in an array, searching from the end, and returns the first non-nil result.
local result = Array.reverseFindMap({ 1, 2, 3, 4, 5 }, function(element)
if element % 2 == 0 then
return element * 2
end
return nil
end)
-- result is 8Optionally, a starting index can be provided to begin the search from a specific position.
local result = Array.reverseFindMap({ 1, 2, 3, 4, 5 }, function(element)
if element % 2 == 0 then
return element * 2
end
return nil
end, 3)
-- result is 4Related: findMap, reverseFind, reverseFindIndex, reverseFindIndexByValue
For a given array, the function returns a new one with its element sorted.
An optional comparator function can be provided to customize how the elements are compared.
For an array of less than 2 elements, this function will return the same array.
local array = {
{ name = 'Charlie' },
{ name = 'Alice' },
{ name = 'Bob' },
}
local result = Array.sort(array, function(a, b)
return value.name < value.name
end)
-- result is {
-- { name = 'Alice' },
-- { name = 'Bob' },
-- { name = 'Charlie' },
-- }Related sortByKey
Sorts an array of objects based on a mapping function results.
local array = {
{ name = 'Charlie' },
{ name = 'Alice' },
{ name = 'Bob' },
}
local result = Array.sortByKey(array, function(value)
return value.name
end)
-- result is {
-- { name = 'Alice' },
-- { name = 'Bob' },
-- { name = 'Charlie' },
-- }Related sort
Create a new array by selecting elements every given step amount.
local originalArray = { "1", "2", "3", "4", "5" }
local result = Array.stepBy(originalArray, 2)
-- result is { "1", "3", "5" }Note: The function supports both positive and negative step values. A negative step value takes elements in reverse.
Calculates the sum of an array of numbers.
local total = Array.sum({20, 10, 30})
-- total is 60Related sumBy, product, productBy
Calculates the sum of an array given a mapping function that produces numbers.
local array = {
{ price = 20 },
{ price = 10 },
{ price = 30 },
}
local total = Array.sumBy(array, function(item)
return item.price
end)
-- total is 60Related sum, product, productBy
Create a new array from the start of the original array, up to the first element that does not satisfy a given condition.
local originalArray = { 3, 1, 4, 1, 5, 3, 1, 9}
local result = Array.takeWhile(originalArray, function(element)
return element <= 5
end)
-- result is { 3, 1, 4, 1, 5 }Note: The function also supports an optional `start`` parameter which skips the first elements.
Combine multiple arrays into a single array of tuples, which are just arrays in Luau. The tuples (or sub-arrays) contains the i-th elements from each of the input arrays.
Note: The resulting array's length is determined by the shortest input array. Extra elements from longer arrays are skipped.
local array1 = {1, 2, 3}
local array2 = {'a', 'b', 'c'}
local array3 = {true, false, true}
local result = Array.zip(array1, array2, array3)
-- result is { {1, 'a', true}, {2, 'b', false}, {3, 'c', true} }