Skip to content

Instantly share code, notes, and snippets.

@howmanysmall
Last active February 13, 2022 20:00
Show Gist options
  • Save howmanysmall/ba0049fcc627565e0e2f60631ce896ec to your computer and use it in GitHub Desktop.
Save howmanysmall/ba0049fcc627565e0e2f60631ce896ec to your computer and use it in GitHub Desktop.
local function AlwaysTrue()
return true
end
local function EqualObjects(...)
local FirstObject = select(1, ...)
for Index = 2, select("#", ...) do
if FirstObject ~= select(Index, ...) then
return false
end
end
return true
end
local function IsEmpty(Table)
return next(Table) == nil
end
local None = setmetatable({}, {
__tostring = function()
return "None"
end;
})
local Dictionary = {}
function Dictionary.Copy(Table)
local NewTable = {}
for Index, Value in next, Table do
NewTable[Index] = Value
end
return NewTable
end
do
local function CopyDeep(Table)
local NewTable = {}
for Index, Value in next, Table do
if type(Value) == "table" then
NewTable[Index] = CopyDeep(Value)
else
NewTable[Index] = Value
end
end
return NewTable
end
Dictionary.CopyDeep = CopyDeep
end
function Dictionary.Count(Table, Function)
Function = Function or AlwaysTrue
local Counter = 0
for Index, Value in next, Table do
if Function(Value, Index) then
Counter = Counter + 1
end
end
return Counter
end
do
local function Compare(A, B)
if type(A) ~= "table" or type(B) ~= "table" then
return A == B
end
for Index, Value in next, A do
if B[Index] ~= Value then
return false
end
end
for Index, Value in next, B do
if A[Index] ~= Value then
return false
end
end
return true
end
local function Equals(...)
if EqualObjects(...) then
return true
end
local Length = select("#", ...)
local FirstObject = select(1, ...)
for Index = 2, Length do
local Object = select(Index, ...)
if not Compare(FirstObject, Object) then
return false
end
end
return true
end
Dictionary.Equals = Equals
end
do
local function CompareDeep(A, B)
if type(A) ~= "table" or type(B) ~= "table" then
return A == B
end
for Index, Value in next, A do
if not CompareDeep(B[Index], Value) then
return false
end
end
for Index, Value in next, B do
if not CompareDeep(A[Index], Value) then
return false
end
end
return true
end
local function EqualsDeep(...)
if EqualObjects(...) then
return true
end
local Length = select("#", ...)
local FirstObject = select(1, ...)
for Index = 2, Length do
local Object = select(Index, ...)
if not CompareDeep(FirstObject, Object) then
return false
end
end
return true
end
Dictionary.EqualsDeep = EqualsDeep
end
function Dictionary.Every(Table, Function)
for Index, Value in next, Table do
if not Function(Value, Index) then
return false
end
end
return true
end
function Dictionary.Filter(Table, Function)
local NewTable = {}
for Index, Value in next, Table do
if Function(Value, Index) then
NewTable[Index] = Value
end
end
return NewTable
end
do
local function Flatten(Table, Depth)
local NewTable = {}
for Index, Value in next, Table do
if type(Value) == "table" and (not Depth or Depth > 0) then
local SubTable = Flatten(Value, Depth and Depth - 1)
for NewIndex, NewValue in next, NewTable do
SubTable[NewIndex] = NewValue
end
NewTable = SubTable
else
NewTable[Index] = Value
end
end
return NewTable
end
Dictionary.Flatten = Flatten
end
function Dictionary.FromLists(Keys, Values)
local Length = #Keys
assert(Length == #Values, "lists must be same size")
local Table = {}
for Index = 1, Length do
Table[Keys[Index]] = Values[Index]
end
return Table
end
function Dictionary.Keys(Table)
local Keys = {}
local Length = 0
for Key in next, Table do
Length = Length + 1
Keys[Length] = Key
end
return Keys
end
function Dictionary.Map(Table, Function)
local NewTable = {}
for Index, Value in next, Table do
local NewValue, NewIndex = Function(Value, Index)
NewTable[NewIndex or Index] = NewValue
end
return NewTable
end
function Dictionary.Join(...)
local NewTable = {}
for Index = 1, select("#", ...) do
local Table = select(Index, ...)
if Table then
for Key, Value in next, Table do
if Value == None then
NewTable[Key] = nil
else
NewTable[Key] = Value
end
end
end
end
return NewTable
end
function Dictionary.Values(Table)
local Values = {}
local Length = 0
for _, Value in next, Table do
Length = Length + 1
Values[Length] = Value
end
return Values
end
local List = {}
function List.Sort(Array, Function)
local NewArray = {}
for Index = 1, #Array do
NewArray[Index] = Array[Index]
end
table.sort(NewArray, Function)
return NewArray
end
function List.Reverse(Array)
local NewArray = {}
local Length = #Array
local Top = Length + 1
for Index = 1, Length do
NewArray[Index] = Array[Top - Index]
end
return NewArray
end
function List.ReplaceIndex(Array, ReplaceIndex, Value)
local Length = #Array
assert(ReplaceIndex <= Length, "index must be less or equal than the list length")
local NewArray = {}
for Index = 1, Length do
if Index == ReplaceIndex then
NewArray[Index] = Value
else
NewArray[Index] = Array[Index]
end
end
return NewArray
end
function List.Map(Array, Function)
local NewArray = {}
for Index = 1, #Array do
NewArray[Index] = Function(Array[Index], Index)
end
return NewArray
end
function List.Join(...)
local NewArray = {}
local Length = 0
for IterateIndex = 1, select("#", ...) do
local Array = select(IterateIndex, ...)
if Array then
for Index = 1, #Array do
local Value = Array[Index]
if Value == None then
Length = Length - 1
else
NewArray[Length + Index] = Value
end
end
end
end
return NewArray
end
function List.Find(Array, Value, Init)
for Index = Init or 1, #Array do
if rawget(Array, Index) == Value then
return Index
end
end
return nil
end
function List.FilterMap(Array, Function)
local NewArray = {}
local Length = 0
for Index = 1, #Array do
local Value = Function(Array[Index], Index)
if Value ~= nil then
Length = Length + 1
NewArray[Length] = Value
end
end
return NewArray
end
function List.Filter(Array, Function)
local NewArray = {}
local Length = 0
for Index = 1, #Array do
local Value = Array[Index]
if Function(Value, Index) then
Length = Length + 1
NewArray[Length] = Value
end
end
return NewArray
end
local Immutable = {}
Immutable.Array = List
Immutable.Dictionary = Dictionary
Immutable.List = List
Immutable.EqualObjects = EqualObjects
Immutable.IsEmpty = IsEmpty
Immutable.None = None
return Immutable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment