diff --git a/sourcemap.json b/sourcemap.json index bf5b04a..819ca2e 100644 --- a/sourcemap.json +++ b/sourcemap.json @@ -1 +1 @@ -{"name":"TableUtil","className":"DataModel","filePaths":["place.project.json"],"children":[{"name":"ReplicatedFirst","className":"ReplicatedFirst","children":[{"name":"TableUtil","className":"ModuleScript","filePaths":["src\\init.lua"],"children":[{"name":"Array","className":"ModuleScript","filePaths":["src\\Array\\init.lua"],"children":[{"name":"BinarySearch","className":"ModuleScript","filePaths":["src\\Array\\BinarySearch.lua"]},{"name":"BinarySearch.spec","className":"ModuleScript","filePaths":["src\\Array\\BinarySearch.spec.lua"]},{"name":"Cut","className":"ModuleScript","filePaths":["src\\Array\\Cut.lua"]},{"name":"Cut.spec","className":"ModuleScript","filePaths":["src\\Array\\Cut.spec.lua"]},{"name":"Filter","className":"ModuleScript","filePaths":["src\\Array\\Filter.lua"]},{"name":"Filter.spec","className":"ModuleScript","filePaths":["src\\Array\\Filter.spec.lua"]},{"name":"FoldLeft","className":"ModuleScript","filePaths":["src\\Array\\FoldLeft.lua"]},{"name":"FoldLeft.spec","className":"ModuleScript","filePaths":["src\\Array\\FoldLeft.spec.lua"]},{"name":"FoldRight","className":"ModuleScript","filePaths":["src\\Array\\FoldRight.lua"]},{"name":"FoldRight.spec","className":"ModuleScript","filePaths":["src\\Array\\FoldRight.spec.lua"]},{"name":"GroupBy","className":"ModuleScript","filePaths":["src\\Array\\GroupBy.lua"]},{"name":"GroupBy.spec","className":"ModuleScript","filePaths":["src\\Array\\GroupBy.spec.lua"]},{"name":"Insert","className":"ModuleScript","filePaths":["src\\Array\\Insert.lua"]},{"name":"Insert.spec","className":"ModuleScript","filePaths":["src\\Array\\Insert.spec.lua"]},{"name":"IsArray","className":"ModuleScript","filePaths":["src\\Array\\IsArray.lua"]},{"name":"IsArray.spec","className":"ModuleScript","filePaths":["src\\Array\\IsArray.spec.lua"]},{"name":"IsOrdered","className":"ModuleScript","filePaths":["src\\Array\\IsOrdered.lua"]},{"name":"IsOrdered.spec","className":"ModuleScript","filePaths":["src\\Array\\IsOrdered.spec.lua"]},{"name":"IsPureArray","className":"ModuleScript","filePaths":["src\\Array\\IsPureArray.lua"]},{"name":"IsPureArray.spec","className":"ModuleScript","filePaths":["src\\Array\\IsPureArray.spec.lua"]},{"name":"Map","className":"ModuleScript","filePaths":["src\\Array\\Map.lua"]},{"name":"Map.spec","className":"ModuleScript","filePaths":["src\\Array\\Map.spec.lua"]},{"name":"Mean","className":"ModuleScript","filePaths":["src\\Array\\Mean.lua"]},{"name":"Mean.spec","className":"ModuleScript","filePaths":["src\\Array\\Mean.spec.lua"]},{"name":"Merge","className":"ModuleScript","filePaths":["src\\Array\\Merge.lua"]},{"name":"Merge.spec","className":"ModuleScript","filePaths":["src\\Array\\Merge.spec.lua"]},{"name":"MergeMany","className":"ModuleScript","filePaths":["src\\Array\\MergeMany.lua"]},{"name":"MergeMany.spec","className":"ModuleScript","filePaths":["src\\Array\\MergeMany.spec.lua"]},{"name":"MutableBinaryInsert","className":"ModuleScript","filePaths":["src\\Array\\MutableBinaryInsert.lua"]},{"name":"MutableBinaryInsert.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableBinaryInsert.spec.lua"]},{"name":"MutableMerge","className":"ModuleScript","filePaths":["src\\Array\\MutableMerge.lua"]},{"name":"MutableMerge.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableMerge.spec.lua"]},{"name":"MutableMergeMany","className":"ModuleScript","filePaths":["src\\Array\\MutableMergeMany.lua"]},{"name":"MutableMergeMany.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableMergeMany.spec.lua"]},{"name":"MutableReverse","className":"ModuleScript","filePaths":["src\\Array\\MutableReverse.lua"]},{"name":"MutableReverse.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableReverse.spec.lua"]},{"name":"MutableShuffle","className":"ModuleScript","filePaths":["src\\Array\\MutableShuffle.lua"]},{"name":"MutableShuffle.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableShuffle.spec.lua"]},{"name":"Percentile","className":"ModuleScript","filePaths":["src\\Array\\Percentile.lua"]},{"name":"Percentile.spec","className":"ModuleScript","filePaths":["src\\Array\\Percentile.spec.lua"]},{"name":"Product","className":"ModuleScript","filePaths":["src\\Array\\Product.lua"]},{"name":"Product.spec","className":"ModuleScript","filePaths":["src\\Array\\Product.spec.lua"]},{"name":"Range","className":"ModuleScript","filePaths":["src\\Array\\Range.lua"]},{"name":"Range.spec","className":"ModuleScript","filePaths":["src\\Array\\Range.spec.lua"]},{"name":"Remove","className":"ModuleScript","filePaths":["src\\Array\\Remove.lua"]},{"name":"Remove.spec","className":"ModuleScript","filePaths":["src\\Array\\Remove.spec.lua"]},{"name":"Reverse","className":"ModuleScript","filePaths":["src\\Array\\Reverse.lua"]},{"name":"Reverse.spec","className":"ModuleScript","filePaths":["src\\Array\\Reverse.spec.lua"]},{"name":"SelectFirst","className":"ModuleScript","filePaths":["src\\Array\\SelectFirst.lua"]},{"name":"SelectFirst.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectFirst.spec.lua"]},{"name":"SelectLast","className":"ModuleScript","filePaths":["src\\Array\\SelectLast.lua"]},{"name":"SelectLast.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectLast.spec.lua"]},{"name":"SelectRandom","className":"ModuleScript","filePaths":["src\\Array\\SelectRandom.lua"]},{"name":"SelectRandom.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectRandom.spec.lua"]},{"name":"SelectWeighted","className":"ModuleScript","filePaths":["src\\Array\\SelectWeighted.lua"]},{"name":"SelectWeighted.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectWeighted.spec.lua"]},{"name":"Shuffle","className":"ModuleScript","filePaths":["src\\Array\\Shuffle.lua"]},{"name":"Shuffle.spec","className":"ModuleScript","filePaths":["src\\Array\\Shuffle.spec.lua"]},{"name":"Sort","className":"ModuleScript","filePaths":["src\\Array\\Sort.lua"]},{"name":"Sort.spec","className":"ModuleScript","filePaths":["src\\Array\\Sort.spec.lua"]},{"name":"Sum","className":"ModuleScript","filePaths":["src\\Array\\Sum.lua"]},{"name":"Sum.spec","className":"ModuleScript","filePaths":["src\\Array\\Sum.spec.lua"]}]},{"name":"Map","className":"ModuleScript","filePaths":["src\\Map\\init.lua"],"children":[{"name":"Changes","className":"ModuleScript","filePaths":["src\\Map\\Changes.lua"]},{"name":"Changes.spec","className":"ModuleScript","filePaths":["src\\Map\\Changes.spec.lua"]},{"name":"CloneDeep","className":"ModuleScript","filePaths":["src\\Map\\CloneDeep.lua"]},{"name":"CloneDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\CloneDeep.spec.lua"]},{"name":"Count","className":"ModuleScript","filePaths":["src\\Map\\Count.lua"]},{"name":"Count.spec","className":"ModuleScript","filePaths":["src\\Map\\Count.spec.lua"]},{"name":"CreatePatchDeep","className":"ModuleScript","filePaths":["src\\Map\\CreatePatchDeep.lua"]},{"name":"CreatePatchDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\CreatePatchDeep.spec.lua"]},{"name":"Creations","className":"ModuleScript","filePaths":["src\\Map\\Creations.lua"]},{"name":"Creations.spec","className":"ModuleScript","filePaths":["src\\Map\\Creations.spec.lua"]},{"name":"Equals","className":"ModuleScript","filePaths":["src\\Map\\Equals.lua"]},{"name":"Equals.spec","className":"ModuleScript","filePaths":["src\\Map\\Equals.spec.lua"]},{"name":"Filter","className":"ModuleScript","filePaths":["src\\Map\\Filter.lua"]},{"name":"Filter.spec","className":"ModuleScript","filePaths":["src\\Map\\Filter.spec.lua"]},{"name":"Flatten","className":"ModuleScript","filePaths":["src\\Map\\Flatten.lua"]},{"name":"Flatten.spec","className":"ModuleScript","filePaths":["src\\Map\\Flatten.spec.lua"]},{"name":"FromKeyValueArray","className":"ModuleScript","filePaths":["src\\Map\\FromKeyValueArray.lua"]},{"name":"FromKeyValueArray.spec","className":"ModuleScript","filePaths":["src\\Map\\FromKeyValueArray.spec.lua"]},{"name":"GroupBy","className":"ModuleScript","filePaths":["src\\Map\\GroupBy.lua"]},{"name":"GroupBy.spec","className":"ModuleScript","filePaths":["src\\Map\\GroupBy.spec.lua"]},{"name":"InverseKeysValues","className":"ModuleScript","filePaths":["src\\Map\\InverseKeysValues.lua"]},{"name":"InverseKeysValues.spec","className":"ModuleScript","filePaths":["src\\Map\\InverseKeysValues.spec.lua"]},{"name":"IsMap","className":"ModuleScript","filePaths":["src\\Map\\IsMap.lua"]},{"name":"IsMap.spec","className":"ModuleScript","filePaths":["src\\Map\\IsMap.spec.lua"]},{"name":"IsMixed","className":"ModuleScript","filePaths":["src\\Map\\IsMixed.lua"]},{"name":"IsMixed.spec","className":"ModuleScript","filePaths":["src\\Map\\IsMixed.spec.lua"]},{"name":"IsPureMap","className":"ModuleScript","filePaths":["src\\Map\\IsPureMap.lua"]},{"name":"IsPureMap.spec","className":"ModuleScript","filePaths":["src\\Map\\IsPureMap.spec.lua"]},{"name":"Keys","className":"ModuleScript","filePaths":["src\\Map\\Keys.lua"]},{"name":"Keys.spec","className":"ModuleScript","filePaths":["src\\Map\\Keys.spec.lua"]},{"name":"Lockdown","className":"ModuleScript","filePaths":["src\\Map\\Lockdown.lua"]},{"name":"Lockdown.spec","className":"ModuleScript","filePaths":["src\\Map\\Lockdown.spec.lua"]},{"name":"Map","className":"ModuleScript","filePaths":["src\\Map\\Map.lua"]},{"name":"Map.spec","className":"ModuleScript","filePaths":["src\\Map\\Map.spec.lua"]},{"name":"Merge","className":"ModuleScript","filePaths":["src\\Map\\Merge.lua"]},{"name":"Merge.spec","className":"ModuleScript","filePaths":["src\\Map\\Merge.spec.lua"]},{"name":"MergeDeep","className":"ModuleScript","filePaths":["src\\Map\\MergeDeep.lua"]},{"name":"MergeDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\MergeDeep.spec.lua"]},{"name":"MergeMany","className":"ModuleScript","filePaths":["src\\Map\\MergeMany.lua"]},{"name":"MergeMany.spec","className":"ModuleScript","filePaths":["src\\Map\\MergeMany.spec.lua"]},{"name":"MutableMerge","className":"ModuleScript","filePaths":["src\\Map\\MutableMerge.lua"]},{"name":"MutableMerge.spec","className":"ModuleScript","filePaths":["src\\Map\\MutableMerge.spec.lua"]},{"name":"MutableMergeDeep","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeDeep.lua"]},{"name":"MutableMergeDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeDeep.spec.lua"]},{"name":"MutableMergeMany","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeMany.lua"]},{"name":"MutableMergeMany.spec","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeMany.spec.lua"]},{"name":"Removals","className":"ModuleScript","filePaths":["src\\Map\\Removals.lua"]},{"name":"Removals.spec","className":"ModuleScript","filePaths":["src\\Map\\Removals.spec.lua"]},{"name":"SetUnresizable","className":"ModuleScript","filePaths":["src\\Map\\SetUnresizable.lua"]},{"name":"SetUnresizable.spec","className":"ModuleScript","filePaths":["src\\Map\\SetUnresizable.spec.lua"]},{"name":"ToKeyValueArray","className":"ModuleScript","filePaths":["src\\Map\\ToKeyValueArray.lua"]},{"name":"ToKeyValueArray.spec","className":"ModuleScript","filePaths":["src\\Map\\ToKeyValueArray.spec.lua"]},{"name":"Values","className":"ModuleScript","filePaths":["src\\Map\\Values.lua"]},{"name":"Values.spec","className":"ModuleScript","filePaths":["src\\Map\\Values.spec.lua"]}]},{"name":"Set","className":"ModuleScript","filePaths":["src\\Set\\init.lua"],"children":[{"name":"Difference","className":"ModuleScript","filePaths":["src\\Set\\Difference.lua"]},{"name":"Difference.spec","className":"ModuleScript","filePaths":["src\\Set\\Difference.spec.lua"]},{"name":"Equals","className":"ModuleScript","filePaths":["src\\Set\\Equals.lua"]},{"name":"Equals.spec","className":"ModuleScript","filePaths":["src\\Set\\Equals.spec.lua"]},{"name":"FromKeys","className":"ModuleScript","filePaths":["src\\Set\\FromKeys.lua"]},{"name":"FromKeys.spec","className":"ModuleScript","filePaths":["src\\Set\\FromKeys.spec.lua"]},{"name":"FromValues","className":"ModuleScript","filePaths":["src\\Set\\FromValues.lua"]},{"name":"FromValues.spec","className":"ModuleScript","filePaths":["src\\Set\\FromValues.spec.lua"]},{"name":"Insert","className":"ModuleScript","filePaths":["src\\Set\\Insert.lua"]},{"name":"Insert.spec","className":"ModuleScript","filePaths":["src\\Set\\Insert.spec.lua"]},{"name":"Intersection","className":"ModuleScript","filePaths":["src\\Set\\Intersection.lua"]},{"name":"Intersection.spec","className":"ModuleScript","filePaths":["src\\Set\\Intersection.spec.lua"]},{"name":"IsProperSubset","className":"ModuleScript","filePaths":["src\\Set\\IsProperSubset.lua"]},{"name":"IsProperSubset.spec","className":"ModuleScript","filePaths":["src\\Set\\IsProperSubset.spec.lua"]},{"name":"IsSubset","className":"ModuleScript","filePaths":["src\\Set\\IsSubset.lua"]},{"name":"IsSubset.spec","className":"ModuleScript","filePaths":["src\\Set\\IsSubset.spec.lua"]},{"name":"Remove","className":"ModuleScript","filePaths":["src\\Set\\Remove.lua"]},{"name":"Remove.spec","className":"ModuleScript","filePaths":["src\\Set\\Remove.spec.lua"]},{"name":"SymmetricDifference","className":"ModuleScript","filePaths":["src\\Set\\SymmetricDifference.lua"]},{"name":"SymmetricDifference.spec","className":"ModuleScript","filePaths":["src\\Set\\SymmetricDifference.spec.lua"]},{"name":"ToArray","className":"ModuleScript","filePaths":["src\\Set\\ToArray.lua"]},{"name":"ToArray.spec","className":"ModuleScript","filePaths":["src\\Set\\ToArray.spec.lua"]},{"name":"Union","className":"ModuleScript","filePaths":["src\\Set\\Union.lua"]},{"name":"Union.spec","className":"ModuleScript","filePaths":["src\\Set\\Union.spec.lua"]},{"name":"_SetType","className":"ModuleScript","filePaths":["src\\Set\\_SetType.lua"]}]},{"name":"_GenerateImports","className":"ModuleScript","filePaths":["src\\_GenerateImports.lua"]}]}]}]} \ No newline at end of file +{"name":"TableUtil","className":"DataModel","filePaths":["place.project.json"],"children":[{"name":"ReplicatedFirst","className":"ReplicatedFirst","children":[{"name":"TableUtil","className":"ModuleScript","filePaths":["src\\init.lua"],"children":[{"name":"Array","className":"ModuleScript","filePaths":["src\\Array\\init.lua"],"children":[{"name":"BinarySearch","className":"ModuleScript","filePaths":["src\\Array\\BinarySearch.lua"]},{"name":"BinarySearch.spec","className":"ModuleScript","filePaths":["src\\Array\\BinarySearch.spec.lua"]},{"name":"Cut","className":"ModuleScript","filePaths":["src\\Array\\Cut.lua"]},{"name":"Cut.spec","className":"ModuleScript","filePaths":["src\\Array\\Cut.spec.lua"]},{"name":"Filter","className":"ModuleScript","filePaths":["src\\Array\\Filter.lua"]},{"name":"Filter.spec","className":"ModuleScript","filePaths":["src\\Array\\Filter.spec.lua"]},{"name":"FoldLeft","className":"ModuleScript","filePaths":["src\\Array\\FoldLeft.lua"]},{"name":"FoldLeft.spec","className":"ModuleScript","filePaths":["src\\Array\\FoldLeft.spec.lua"]},{"name":"FoldRight","className":"ModuleScript","filePaths":["src\\Array\\FoldRight.lua"]},{"name":"FoldRight.spec","className":"ModuleScript","filePaths":["src\\Array\\FoldRight.spec.lua"]},{"name":"GroupBy","className":"ModuleScript","filePaths":["src\\Array\\GroupBy.lua"]},{"name":"GroupBy.spec","className":"ModuleScript","filePaths":["src\\Array\\GroupBy.spec.lua"]},{"name":"Insert","className":"ModuleScript","filePaths":["src\\Array\\Insert.lua"]},{"name":"Insert.spec","className":"ModuleScript","filePaths":["src\\Array\\Insert.spec.lua"]},{"name":"IsArray","className":"ModuleScript","filePaths":["src\\Array\\IsArray.lua"]},{"name":"IsArray.spec","className":"ModuleScript","filePaths":["src\\Array\\IsArray.spec.lua"]},{"name":"IsOrdered","className":"ModuleScript","filePaths":["src\\Array\\IsOrdered.lua"]},{"name":"IsOrdered.spec","className":"ModuleScript","filePaths":["src\\Array\\IsOrdered.spec.lua"]},{"name":"IsPureArray","className":"ModuleScript","filePaths":["src\\Array\\IsPureArray.lua"]},{"name":"IsPureArray.spec","className":"ModuleScript","filePaths":["src\\Array\\IsPureArray.spec.lua"]},{"name":"Map","className":"ModuleScript","filePaths":["src\\Array\\Map.lua"]},{"name":"Map.spec","className":"ModuleScript","filePaths":["src\\Array\\Map.spec.lua"]},{"name":"Mean","className":"ModuleScript","filePaths":["src\\Array\\Mean.lua"]},{"name":"Mean.spec","className":"ModuleScript","filePaths":["src\\Array\\Mean.spec.lua"]},{"name":"Merge","className":"ModuleScript","filePaths":["src\\Array\\Merge.lua"]},{"name":"Merge.spec","className":"ModuleScript","filePaths":["src\\Array\\Merge.spec.lua"]},{"name":"MergeMany","className":"ModuleScript","filePaths":["src\\Array\\MergeMany.lua"]},{"name":"MergeMany.spec","className":"ModuleScript","filePaths":["src\\Array\\MergeMany.spec.lua"]},{"name":"MutableBinaryInsert","className":"ModuleScript","filePaths":["src\\Array\\MutableBinaryInsert.lua"]},{"name":"MutableBinaryInsert.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableBinaryInsert.spec.lua"]},{"name":"MutableMerge","className":"ModuleScript","filePaths":["src\\Array\\MutableMerge.lua"]},{"name":"MutableMerge.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableMerge.spec.lua"]},{"name":"MutableMergeMany","className":"ModuleScript","filePaths":["src\\Array\\MutableMergeMany.lua"]},{"name":"MutableMergeMany.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableMergeMany.spec.lua"]},{"name":"MutableReverse","className":"ModuleScript","filePaths":["src\\Array\\MutableReverse.lua"]},{"name":"MutableReverse.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableReverse.spec.lua"]},{"name":"MutableShuffle","className":"ModuleScript","filePaths":["src\\Array\\MutableShuffle.lua"]},{"name":"MutableShuffle.spec","className":"ModuleScript","filePaths":["src\\Array\\MutableShuffle.spec.lua"]},{"name":"Percentile","className":"ModuleScript","filePaths":["src\\Array\\Percentile.lua"]},{"name":"Percentile.spec","className":"ModuleScript","filePaths":["src\\Array\\Percentile.spec.lua"]},{"name":"Product","className":"ModuleScript","filePaths":["src\\Array\\Product.lua"]},{"name":"Product.spec","className":"ModuleScript","filePaths":["src\\Array\\Product.spec.lua"]},{"name":"Range","className":"ModuleScript","filePaths":["src\\Array\\Range.lua"]},{"name":"Range.spec","className":"ModuleScript","filePaths":["src\\Array\\Range.spec.lua"]},{"name":"Remove","className":"ModuleScript","filePaths":["src\\Array\\Remove.lua"]},{"name":"Remove.spec","className":"ModuleScript","filePaths":["src\\Array\\Remove.spec.lua"]},{"name":"Reverse","className":"ModuleScript","filePaths":["src\\Array\\Reverse.lua"]},{"name":"Reverse.spec","className":"ModuleScript","filePaths":["src\\Array\\Reverse.spec.lua"]},{"name":"SelectFirst","className":"ModuleScript","filePaths":["src\\Array\\SelectFirst.lua"]},{"name":"SelectFirst.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectFirst.spec.lua"]},{"name":"SelectLast","className":"ModuleScript","filePaths":["src\\Array\\SelectLast.lua"]},{"name":"SelectLast.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectLast.spec.lua"]},{"name":"SelectRandom","className":"ModuleScript","filePaths":["src\\Array\\SelectRandom.lua"]},{"name":"SelectRandom.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectRandom.spec.lua"]},{"name":"SelectWeighted","className":"ModuleScript","filePaths":["src\\Array\\SelectWeighted.lua"]},{"name":"SelectWeighted.spec","className":"ModuleScript","filePaths":["src\\Array\\SelectWeighted.spec.lua"]},{"name":"Shuffle","className":"ModuleScript","filePaths":["src\\Array\\Shuffle.lua"]},{"name":"Shuffle.spec","className":"ModuleScript","filePaths":["src\\Array\\Shuffle.spec.lua"]},{"name":"Sort","className":"ModuleScript","filePaths":["src\\Array\\Sort.lua"]},{"name":"Sort.spec","className":"ModuleScript","filePaths":["src\\Array\\Sort.spec.lua"]},{"name":"Sum","className":"ModuleScript","filePaths":["src\\Array\\Sum.lua"]},{"name":"Sum.spec","className":"ModuleScript","filePaths":["src\\Array\\Sum.spec.lua"]},{"name":"Equals","className":"ModuleScript","filePaths":["src\\Array\\Equals.lua"]},{"name":"Equals.spec","className":"ModuleScript","filePaths":["src\\Array\\Equals.spec.lua"]}]},{"name":"Map","className":"ModuleScript","filePaths":["src\\Map\\init.lua"],"children":[{"name":"Changes","className":"ModuleScript","filePaths":["src\\Map\\Changes.lua"]},{"name":"Changes.spec","className":"ModuleScript","filePaths":["src\\Map\\Changes.spec.lua"]},{"name":"CloneDeep","className":"ModuleScript","filePaths":["src\\Map\\CloneDeep.lua"]},{"name":"CloneDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\CloneDeep.spec.lua"]},{"name":"Count","className":"ModuleScript","filePaths":["src\\Map\\Count.lua"]},{"name":"Count.spec","className":"ModuleScript","filePaths":["src\\Map\\Count.spec.lua"]},{"name":"CreatePatchDeep","className":"ModuleScript","filePaths":["src\\Map\\CreatePatchDeep.lua"]},{"name":"CreatePatchDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\CreatePatchDeep.spec.lua"]},{"name":"Creations","className":"ModuleScript","filePaths":["src\\Map\\Creations.lua"]},{"name":"Creations.spec","className":"ModuleScript","filePaths":["src\\Map\\Creations.spec.lua"]},{"name":"Equals","className":"ModuleScript","filePaths":["src\\Map\\Equals.lua"]},{"name":"Equals.spec","className":"ModuleScript","filePaths":["src\\Map\\Equals.spec.lua"]},{"name":"Filter","className":"ModuleScript","filePaths":["src\\Map\\Filter.lua"]},{"name":"Filter.spec","className":"ModuleScript","filePaths":["src\\Map\\Filter.spec.lua"]},{"name":"Flatten","className":"ModuleScript","filePaths":["src\\Map\\Flatten.lua"]},{"name":"Flatten.spec","className":"ModuleScript","filePaths":["src\\Map\\Flatten.spec.lua"]},{"name":"FromKeyValueArray","className":"ModuleScript","filePaths":["src\\Map\\FromKeyValueArray.lua"]},{"name":"FromKeyValueArray.spec","className":"ModuleScript","filePaths":["src\\Map\\FromKeyValueArray.spec.lua"]},{"name":"GroupBy","className":"ModuleScript","filePaths":["src\\Map\\GroupBy.lua"]},{"name":"GroupBy.spec","className":"ModuleScript","filePaths":["src\\Map\\GroupBy.spec.lua"]},{"name":"IsMap","className":"ModuleScript","filePaths":["src\\Map\\IsMap.lua"]},{"name":"IsMap.spec","className":"ModuleScript","filePaths":["src\\Map\\IsMap.spec.lua"]},{"name":"IsMixed","className":"ModuleScript","filePaths":["src\\Map\\IsMixed.lua"]},{"name":"IsMixed.spec","className":"ModuleScript","filePaths":["src\\Map\\IsMixed.spec.lua"]},{"name":"IsPureMap","className":"ModuleScript","filePaths":["src\\Map\\IsPureMap.lua"]},{"name":"IsPureMap.spec","className":"ModuleScript","filePaths":["src\\Map\\IsPureMap.spec.lua"]},{"name":"Keys","className":"ModuleScript","filePaths":["src\\Map\\Keys.lua"]},{"name":"Keys.spec","className":"ModuleScript","filePaths":["src\\Map\\Keys.spec.lua"]},{"name":"Lockdown","className":"ModuleScript","filePaths":["src\\Map\\Lockdown.lua"]},{"name":"Lockdown.spec","className":"ModuleScript","filePaths":["src\\Map\\Lockdown.spec.lua"]},{"name":"Map","className":"ModuleScript","filePaths":["src\\Map\\Map.lua"]},{"name":"Map.spec","className":"ModuleScript","filePaths":["src\\Map\\Map.spec.lua"]},{"name":"Merge","className":"ModuleScript","filePaths":["src\\Map\\Merge.lua"]},{"name":"Merge.spec","className":"ModuleScript","filePaths":["src\\Map\\Merge.spec.lua"]},{"name":"MergeDeep","className":"ModuleScript","filePaths":["src\\Map\\MergeDeep.lua"]},{"name":"MergeDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\MergeDeep.spec.lua"]},{"name":"MergeMany","className":"ModuleScript","filePaths":["src\\Map\\MergeMany.lua"]},{"name":"MergeMany.spec","className":"ModuleScript","filePaths":["src\\Map\\MergeMany.spec.lua"]},{"name":"MutableMerge","className":"ModuleScript","filePaths":["src\\Map\\MutableMerge.lua"]},{"name":"MutableMerge.spec","className":"ModuleScript","filePaths":["src\\Map\\MutableMerge.spec.lua"]},{"name":"MutableMergeDeep","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeDeep.lua"]},{"name":"MutableMergeDeep.spec","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeDeep.spec.lua"]},{"name":"MutableMergeMany","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeMany.lua"]},{"name":"MutableMergeMany.spec","className":"ModuleScript","filePaths":["src\\Map\\MutableMergeMany.spec.lua"]},{"name":"Removals","className":"ModuleScript","filePaths":["src\\Map\\Removals.lua"]},{"name":"Removals.spec","className":"ModuleScript","filePaths":["src\\Map\\Removals.spec.lua"]},{"name":"SetUnresizable","className":"ModuleScript","filePaths":["src\\Map\\SetUnresizable.lua"]},{"name":"SetUnresizable.spec","className":"ModuleScript","filePaths":["src\\Map\\SetUnresizable.spec.lua"]},{"name":"SwapKeysValues","className":"ModuleScript","filePaths":["src\\Map\\SwapKeysValues.lua"]},{"name":"SwapKeysValues.spec","className":"ModuleScript","filePaths":["src\\Map\\SwapKeysValues.spec.lua"]},{"name":"ToKeyValueArray","className":"ModuleScript","filePaths":["src\\Map\\ToKeyValueArray.lua"]},{"name":"ToKeyValueArray.spec","className":"ModuleScript","filePaths":["src\\Map\\ToKeyValueArray.spec.lua"]},{"name":"Values","className":"ModuleScript","filePaths":["src\\Map\\Values.lua"]},{"name":"Values.spec","className":"ModuleScript","filePaths":["src\\Map\\Values.spec.lua"]}]},{"name":"Set","className":"ModuleScript","filePaths":["src\\Set\\init.lua"],"children":[{"name":"Difference","className":"ModuleScript","filePaths":["src\\Set\\Difference.lua"]},{"name":"Difference.spec","className":"ModuleScript","filePaths":["src\\Set\\Difference.spec.lua"]},{"name":"Equals","className":"ModuleScript","filePaths":["src\\Set\\Equals.lua"]},{"name":"Equals.spec","className":"ModuleScript","filePaths":["src\\Set\\Equals.spec.lua"]},{"name":"FromKeys","className":"ModuleScript","filePaths":["src\\Set\\FromKeys.lua"]},{"name":"FromKeys.spec","className":"ModuleScript","filePaths":["src\\Set\\FromKeys.spec.lua"]},{"name":"FromValues","className":"ModuleScript","filePaths":["src\\Set\\FromValues.lua"]},{"name":"FromValues.spec","className":"ModuleScript","filePaths":["src\\Set\\FromValues.spec.lua"]},{"name":"Insert","className":"ModuleScript","filePaths":["src\\Set\\Insert.lua"]},{"name":"Insert.spec","className":"ModuleScript","filePaths":["src\\Set\\Insert.spec.lua"]},{"name":"Intersection","className":"ModuleScript","filePaths":["src\\Set\\Intersection.lua"]},{"name":"Intersection.spec","className":"ModuleScript","filePaths":["src\\Set\\Intersection.spec.lua"]},{"name":"IsProperSubset","className":"ModuleScript","filePaths":["src\\Set\\IsProperSubset.lua"]},{"name":"IsProperSubset.spec","className":"ModuleScript","filePaths":["src\\Set\\IsProperSubset.spec.lua"]},{"name":"IsSubset","className":"ModuleScript","filePaths":["src\\Set\\IsSubset.lua"]},{"name":"IsSubset.spec","className":"ModuleScript","filePaths":["src\\Set\\IsSubset.spec.lua"]},{"name":"Remove","className":"ModuleScript","filePaths":["src\\Set\\Remove.lua"]},{"name":"Remove.spec","className":"ModuleScript","filePaths":["src\\Set\\Remove.spec.lua"]},{"name":"SymmetricDifference","className":"ModuleScript","filePaths":["src\\Set\\SymmetricDifference.lua"]},{"name":"SymmetricDifference.spec","className":"ModuleScript","filePaths":["src\\Set\\SymmetricDifference.spec.lua"]},{"name":"ToArray","className":"ModuleScript","filePaths":["src\\Set\\ToArray.lua"]},{"name":"ToArray.spec","className":"ModuleScript","filePaths":["src\\Set\\ToArray.spec.lua"]},{"name":"Union","className":"ModuleScript","filePaths":["src\\Set\\Union.lua"]},{"name":"Union.spec","className":"ModuleScript","filePaths":["src\\Set\\Union.spec.lua"]},{"name":"_SetType","className":"ModuleScript","filePaths":["src\\Set\\_SetType.lua"]}]}]}]}]} \ No newline at end of file diff --git a/src/Array/BinarySearch.lua b/src/Array/BinarySearch.lua index 25bbde8..1df408d 100644 --- a/src/Array/BinarySearch.lua +++ b/src/Array/BinarySearch.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Binary search on an ordered array. local function BinarySearch(Array: {T}, Target: T, ReturnClosestIndex: boolean?): number? diff --git a/src/Array/Cut.lua b/src/Array/Cut.lua index 4dd7283..b0cc49f 100644 --- a/src/Array/Cut.lua +++ b/src/Array/Cut.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Cuts a chunk from an array given a starting and ending index - the difference in these indexes can be negative - faster if positive e.g. Cut(X, 1, 4) over Cut(X, 4, 1) local function Cut(Array: {T}, From: number, To: number): {T} @@ -18,8 +19,8 @@ local function Cut(Array: {T}, From: number, To: number): {T} return Array end + -- Faster, but table.move doesn't support iterating backwards over a range. if (Diff > 0) then - -- Faster, but table.move doesn't support iterating backwards over a range return table.move(Array, From, To, 1, {}) end diff --git a/src/Array/Equals.lua b/src/Array/Equals.lua new file mode 100644 index 0000000..1068a05 --- /dev/null +++ b/src/Array/Equals.lua @@ -0,0 +1,20 @@ +--!native +--!optimize 2 +--!nonstrict + +--- Shallow checks if both arrays have equal elements. +local function Equals(X: {any}, Y: {any}): boolean + if (#X ~= #Y) then + return false + end + + for Index, Value in X do + if (Value ~= Y[Index]) then + return false + end + end + + return true +end + +return Equals \ No newline at end of file diff --git a/src/Array/Equals.spec.lua b/src/Array/Equals.spec.lua new file mode 100644 index 0000000..f7a3b0e --- /dev/null +++ b/src/Array/Equals.spec.lua @@ -0,0 +1,27 @@ +return function() + local Equals = require(script.Parent.Equals) + + describe("Array/Equals", function() + it("should return true for two empty tables", function() + expect(Equals({}, {})).to.equal(true) + end) + + it("should return false for one item in X and none in Y", function() + expect(Equals({"Test"}, {})).to.equal(false) + end) + + it("should return false for one item in Y and none in X", function() + expect(Equals({}, {"Test"})).to.equal(false) + end) + + it("should return false for arrays of differnet sizes", function() + expect(Equals({1, 2, 3}, {1, 2})).to.equal(false) + expect(Equals({1, 2}, {1, 2, 3})).to.equal(false) + end) + + it("should return true for two equal arrays", function() + expect(Equals({1, 2, 3}, {1, 2, 3})).to.equal(true) + expect(Equals({1}, {1})).to.equal(true) + end) + end) +end \ No newline at end of file diff --git a/src/Array/Filter.lua b/src/Array/Filter.lua index bca165b..dc911a4 100644 --- a/src/Array/Filter.lua +++ b/src/Array/Filter.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Filters an array for all items which satisfy some condition. local function Filter(Array: {T}, Condition: (T, number) -> boolean, Allocate: number?): {T} diff --git a/src/Array/FoldLeft.lua b/src/Array/FoldLeft.lua index 7d730da..4ae5243 100644 --- a/src/Array/FoldLeft.lua +++ b/src/Array/FoldLeft.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Reduces an array to a single value from its left-most value to its right-most value. local function FoldLeft(Array: {T}, Processor: (T, T, number, number) -> T, Initial: T): T diff --git a/src/Array/FoldRight.lua b/src/Array/FoldRight.lua index e2ae7fe..e277803 100644 --- a/src/Array/FoldRight.lua +++ b/src/Array/FoldRight.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Reduces an array to a single value from its right-most value to its left-most value. local function FoldRight(Array: {T}, Processor: (T, T, number, number) -> T, Initial: T): T diff --git a/src/Array/GroupBy.lua b/src/Array/GroupBy.lua index be8abe1..692f566 100644 --- a/src/Array/GroupBy.lua +++ b/src/Array/GroupBy.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Groups the elements of an array into buckets based on the key returned by the grouper function. --- Example: GroupBy({1, 2, 3, 4, 5}, function(Value) return Value % 2 end) --> {[0] = {2, 4}, [1] = {1, 3, 5}} @@ -8,13 +9,11 @@ local function GroupBy(Structure: {[number]: Entry}, Grouper: ((Entry, nu for Key, Value in Structure do local NewKey = Grouper(Value, Key) - if (NewKey == nil) then continue end local Target = Result[NewKey] - if (Target) then table.insert(Target, Value) continue diff --git a/src/Array/Insert.lua b/src/Array/Insert.lua index 14d1a1a..da3cc7e 100644 --- a/src/Array/Insert.lua +++ b/src/Array/Insert.lua @@ -1,18 +1,17 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Inserts a value into a new array with an optional "insert at" index. local function Insert(Array: {T}, Value: T, At: number?): {T} local NewSize = #Array + 1 local Result = table.create(NewSize) At = At or NewSize - assert(At >= 1 and At <= NewSize, "Insert index out of array range") - table.move(Array, 1, At - 1, 1, Result) + table.move(Array, 1, At :: number - 1, 1, Result) Result[At] = Value - table.move(Array, At, NewSize - 1, At + 1, Result) - + table.move(Array, At :: number, NewSize - 1, At :: number + 1, Result) return Result end diff --git a/src/Array/IsArray.lua b/src/Array/IsArray.lua index 643ae1c..a42ad40 100644 --- a/src/Array/IsArray.lua +++ b/src/Array/IsArray.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Checks if the input table has an *array component*. Not mutually exclusive to IsMap. local function IsArray(Structure: {[any]: any}): boolean diff --git a/src/Array/IsOrdered.lua b/src/Array/IsOrdered.lua index 67601e3..124a170 100644 --- a/src/Array/IsOrdered.lua +++ b/src/Array/IsOrdered.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local function _IsOrdered(Structure: {any}, AscendingOrDescending: boolean?): (boolean) -- Check ascending. @@ -8,11 +9,9 @@ local function _IsOrdered(Structure: {any}, AscendingOrDescending: boolean?): (b for Index = 2, #Structure do local Value = Structure[Index] - if (Value < LastValue) then return false end - LastValue = Value end @@ -24,11 +23,9 @@ local function _IsOrdered(Structure: {any}, AscendingOrDescending: boolean?): (b for Index = 2, #Structure do local Value = Structure[Index] - if (Value > LastValue) then return false end - LastValue = Value end @@ -43,7 +40,6 @@ local function IsOrdered(Structure: {any}, AscendingOrDescendingOrEither: boolea if (AscendingOrDescendingOrEither == nil and Structure[1] ~= nil and Structure[2] ~= nil) then return _IsOrdered(Structure, Structure[1] < Structure[2]) end - return _IsOrdered(Structure, AscendingOrDescendingOrEither) end diff --git a/src/Array/IsPureArray.lua b/src/Array/IsPureArray.lua index 4536abe..cfd8cfa 100644 --- a/src/Array/IsPureArray.lua +++ b/src/Array/IsPureArray.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local IsArray = require(script.Parent:WaitForChild("IsArray")) local IsMap = require(script.Parent.Parent:WaitForChild("Map"):WaitForChild("IsMap")) diff --git a/src/Array/Map.lua b/src/Array/Map.lua index 98e2737..b1e8000 100644 --- a/src/Array/Map.lua +++ b/src/Array/Map.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Puts an array's values through a transformation function, mapping the outputs into a new array - nil values will be skipped & will not leave holes in the new array. local function Map(Array: {T}, Operator: (T, number) -> T?, Allocate: number?): {T} @@ -7,11 +8,10 @@ local function Map(Array: {T}, Operator: (T, number) -> T?, Allocate: number? local Index = 1 for ItemIndex = 1, #Array do - local Value = Array[ItemIndex] - local Transformed = Operator(Value, ItemIndex) + local Transformed = Operator(Array[ItemIndex], ItemIndex) + -- Skip nil values. if (Transformed == nil) then - -- Skip nil values continue end diff --git a/src/Array/Mean.lua b/src/Array/Mean.lua index 086fed1..c88dccf 100644 --- a/src/Array/Mean.lua +++ b/src/Array/Mean.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local function Mean(Array: {T}, From: number?, To: number?): T From = From or 1 diff --git a/src/Array/Merge.lua b/src/Array/Merge.lua index 3ff7b36..858b096 100644 --- a/src/Array/Merge.lua +++ b/src/Array/Merge.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Merges two arrays together. local function Merge(Into: {V1}, New: {V2}): {V1 | V2} diff --git a/src/Array/MergeMany.lua b/src/Array/MergeMany.lua index 2231b4c..e5fdbbf 100644 --- a/src/Array/MergeMany.lua +++ b/src/Array/MergeMany.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Merges multiple arrays together, in order. local function MergeMany(...: {T}): {T} diff --git a/src/Array/MutableBinaryInsert.lua b/src/Array/MutableBinaryInsert.lua index 20c8515..ac2d5cf 100644 --- a/src/Array/MutableBinaryInsert.lua +++ b/src/Array/MutableBinaryInsert.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local BinarySearch = require(script.Parent:WaitForChild("BinarySearch")) diff --git a/src/Array/MutableMerge.lua b/src/Array/MutableMerge.lua index a5c80f6..56c580e 100644 --- a/src/Array/MutableMerge.lua +++ b/src/Array/MutableMerge.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Merges the second given array into the first. local function MutableMerge(Into: {any}, New: {any}) diff --git a/src/Array/MutableMergeMany.lua b/src/Array/MutableMergeMany.lua index 07a6a74..188f8fc 100644 --- a/src/Array/MutableMergeMany.lua +++ b/src/Array/MutableMergeMany.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Merges the second given array into the first. local function MutableMergeMany(Into: {any}, ...: {any}) diff --git a/src/Array/MutableReverse.lua b/src/Array/MutableReverse.lua index 5737496..a18545b 100644 --- a/src/Array/MutableReverse.lua +++ b/src/Array/MutableReverse.lua @@ -1,11 +1,12 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Flips all items in an array. local function MutableReverse(Array: {T}) local ArraySize = #Array - for Index = 1, math.floor(ArraySize / 2) do + for Index = 1, ArraySize // 2 do local Other = ArraySize - Index + 1 Array[Index], Array[Other] = Array[Other], Array[Index] end diff --git a/src/Array/MutableShuffle.lua b/src/Array/MutableShuffle.lua index b2b4366..8f65802 100644 --- a/src/Array/MutableShuffle.lua +++ b/src/Array/MutableShuffle.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local RandomGenerator = Random.new() diff --git a/src/Array/Percentile.lua b/src/Array/Percentile.lua index 29edebb..de86d5e 100644 --- a/src/Array/Percentile.lua +++ b/src/Array/Percentile.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local function Percentile(OrderedArray: {T}, Percentile: number): T return OrderedArray[math.ceil(#OrderedArray * Percentile)] diff --git a/src/Array/Product.lua b/src/Array/Product.lua index 77f8c3c..4d8b0d9 100644 --- a/src/Array/Product.lua +++ b/src/Array/Product.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Produces a table of all possible combinations of a given dimension. local function Product(Array, Dimension) @@ -23,6 +24,4 @@ local function Product(Array, Dimension) return Result end -print(Product({1, 2}, 3)) - return Product \ No newline at end of file diff --git a/src/Array/Range.lua b/src/Array/Range.lua index 66b029b..7ea4b56 100644 --- a/src/Array/Range.lua +++ b/src/Array/Range.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local function Range(Min: number, Max: number): {number} if (Min > Max) then diff --git a/src/Array/Remove.lua b/src/Array/Remove.lua index f26b624..0eb09b6 100644 --- a/src/Array/Remove.lua +++ b/src/Array/Remove.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Removes a single element from an array. local function Remove(Array: {T}, Index: number?): {T} @@ -15,9 +16,8 @@ local function Remove(Array: {T}, Index: number?): {T} assert(Index <= ArrayLength, "Index out of bounds") local Result = table.create(ArrayLength - 1) - table.move(Array, 1, Index - 1, 1, Result) - table.move(Array, Index + 1, ArrayLength, Index, Result) - + table.move(Array, 1, Index :: number - 1, 1, Result) + table.move(Array, Index :: number + 1, ArrayLength, Index :: number, Result) return Result end diff --git a/src/Array/Reverse.lua b/src/Array/Reverse.lua index 7a643a8..a34f51a 100644 --- a/src/Array/Reverse.lua +++ b/src/Array/Reverse.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local MutableReverse = require(script.Parent:WaitForChild("MutableReverse")) diff --git a/src/Array/SelectFirst.lua b/src/Array/SelectFirst.lua index 10c98a1..7d63ffc 100644 --- a/src/Array/SelectFirst.lua +++ b/src/Array/SelectFirst.lua @@ -1,11 +1,11 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Selects the first item in an array which satisfies some condition. local function SelectFirst(Array: {T}, Condition: (T, number) -> boolean): (T?, number?) for Index = 1, #Array do local Value = Array[Index] - if (Condition(Value, Index)) then return Value, Index end diff --git a/src/Array/SelectLast.lua b/src/Array/SelectLast.lua index d4b4ea2..e938d99 100644 --- a/src/Array/SelectLast.lua +++ b/src/Array/SelectLast.lua @@ -1,11 +1,11 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Selects the last item in an array which satisfies some condition. local function SelectLast(Array: {T}, Condition: (T, number) -> boolean): (T?, number?) for Index = #Array, 1, -1 do local Value = Array[Index] - if (Condition(Value, Index)) then return Value, Index end diff --git a/src/Array/SelectRandom.lua b/src/Array/SelectRandom.lua index 336f9f0..4a05cfb 100644 --- a/src/Array/SelectRandom.lua +++ b/src/Array/SelectRandom.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local RandomGen = Random.new() diff --git a/src/Array/SelectWeighted.lua b/src/Array/SelectWeighted.lua index ce073e2..7411a20 100644 --- a/src/Array/SelectWeighted.lua +++ b/src/Array/SelectWeighted.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local RandomGen = Random.new() @@ -22,10 +23,8 @@ local function SelectWeighted1D(Array: {V & {}}, WeightKey: string, Seed: num end) local RandomWeight = UseRandom:NextNumber() * TotalWeight - for _, Value in Array do RandomWeight -= Value[WeightKey] - if (RandomWeight <= 0) then return Value end diff --git a/src/Array/Shuffle.lua b/src/Array/Shuffle.lua index e59060c..ac8cc74 100644 --- a/src/Array/Shuffle.lua +++ b/src/Array/Shuffle.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local MutableShuffle = require(script.Parent:WaitForChild("MutableShuffle")) --- Scrambles an array with an optional random seed. diff --git a/src/Array/Sort.lua b/src/Array/Sort.lua index 3e1395c..a14dd08 100644 --- a/src/Array/Sort.lua +++ b/src/Array/Sort.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Copies & sorts an array according to some condition. local function Sort(Array: {T}, Condition: (T, T) -> boolean): {T} diff --git a/src/Array/Sum.lua b/src/Array/Sum.lua index 69f2124..1d6c09d 100644 --- a/src/Array/Sum.lua +++ b/src/Array/Sum.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local function Sum(Array: {T}, From: number?, To: number?): T local Size = #Array @@ -15,12 +16,10 @@ local function Sum(Array: {T}, From: number?, To: number?): T end local Sum = 0 - for Index = From, To, math.sign(To - From) do + for Index = From :: number, To :: number, (To > From and 1 or -1) do Sum += Array[Index] end return Sum end -print(">>>", Sum({1, 2, 3, 4}, 1, 3)) - return Sum \ No newline at end of file diff --git a/src/Array/init.lua b/src/Array/init.lua index 2e39b6c..fa832d5 100644 --- a/src/Array/init.lua +++ b/src/Array/init.lua @@ -1,6 +1,7 @@ return { BinarySearch = require(script.BinarySearch); Cut = require(script.Cut); + Equals = require(script.Equals); Filter = require(script.Filter); FoldLeft = require(script.FoldLeft); FoldRight = require(script.FoldRight); diff --git a/src/Map/Changes.lua b/src/Map/Changes.lua index 4816ea1..018c495 100644 --- a/src/Map/Changes.lua +++ b/src/Map/Changes.lua @@ -1,21 +1,20 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Finds unequal values with the same key, returns a table of the new values from Y. +--- Nil values are ignored. local function Changes(X: {[K]: V}, Y: {[K]: V}): {[K]: V} local Result = {} for Key, Value in X do local YValue = Y[Key] - if (YValue == nil) then continue end - if (YValue == Value) then continue end - Result[Key] = YValue end diff --git a/src/Map/CloneDeep.lua b/src/Map/CloneDeep.lua index e583322..eb98fe0 100644 --- a/src/Map/CloneDeep.lua +++ b/src/Map/CloneDeep.lua @@ -1,11 +1,14 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Copies a data structure on all depth levels. local function CloneDeep(Structure: {[K]: V}): {[K]: V} - local Result = {} + local Result = table.clone(Structure) for Key, Value in Structure do - Result[Key] = if (type(Value) == "table") then CloneDeep(Value) else Value + if (type(Value) == "table") then + Result[Key] = CloneDeep(Value) + end end return Result end diff --git a/src/Map/CloneDeep.spec.lua b/src/Map/CloneDeep.spec.lua index 63ec21f..0e1ba76 100644 --- a/src/Map/CloneDeep.spec.lua +++ b/src/Map/CloneDeep.spec.lua @@ -40,5 +40,23 @@ return function() expect(Copied.Y.W).never.to.equal(Target.Y.W) expect(Copied.Y.W.P).to.equal("Test") end) + + it("should preserve metatables", function() + local MT = {__tostring = function() + return "Test" + end} + local X = { + Y = { + P = 1; + Q = 2; + }; + Z = { + R = 3; + S = 4; + AHHH = setmetatable({}, MT); + }; + } + expect(getmetatable(CloneDeep(X).Z.AHHH)).to.equal(MT) + end) end) end \ No newline at end of file diff --git a/src/Map/Count.lua b/src/Map/Count.lua index e8bba08..abdbd3d 100644 --- a/src/Map/Count.lua +++ b/src/Map/Count.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Counts the number of elements in a flat table. local function Count(Structure: {[any]: any}): numbers diff --git a/src/Map/CreatePatchDeep.lua b/src/Map/CreatePatchDeep.lua index 83293d0..5278891 100644 --- a/src/Map/CreatePatchDeep.lua +++ b/src/Map/CreatePatchDeep.lua @@ -1,5 +1,8 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict + +-- Todo: support to-overwrite metatables in this. --- Creates a "patch template" into another object recursively. --- This allows us to apply an additional merge to add new fields to values which were not originally nil. diff --git a/src/Map/Creations.lua b/src/Map/Creations.lua index fe9f045..b4d23d0 100644 --- a/src/Map/Creations.lua +++ b/src/Map/Creations.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Finds keys in Y which are not in X (i.e. new values with respect to a base table). local function Creations(X: {[K]: V}, Y: {[K]: V}): {[K]: V} diff --git a/src/Map/Equals.lua b/src/Map/Equals.lua index d11cd3d..3c23b83 100644 --- a/src/Map/Equals.lua +++ b/src/Map/Equals.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Checks if two structures are equal on their top level. local function Equals(X: {[any]: any}, Y: {[any]: any}): boolean diff --git a/src/Map/Filter.lua b/src/Map/Filter.lua index 41eb16e..ca88ce8 100644 --- a/src/Map/Filter.lua +++ b/src/Map/Filter.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Filters a table for all items which satisfy some condition. local function Filter(Structure: {[K]: V}, Condition: (V, K) -> boolean): {[K]: V} diff --git a/src/Map/Flatten.lua b/src/Map/Flatten.lua index 26a87ae..d1908bd 100644 --- a/src/Map/Flatten.lua +++ b/src/Map/Flatten.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Flattens a deep table, merging all sub-tables into the top level. Takes an optional depth limit. local function Flatten(Structure: any, DepthLimit: number?) diff --git a/src/Map/FromKeyValueArray.lua b/src/Map/FromKeyValueArray.lua index 16c6b91..83066a5 100644 --- a/src/Map/FromKeyValueArray.lua +++ b/src/Map/FromKeyValueArray.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Converts a table into an array of key-value objects. local function FromKeyValueArray(Structure: {{Key: K, Value: V}}): {[K]: V} diff --git a/src/Map/GroupBy.lua b/src/Map/GroupBy.lua index bb11893..3636d21 100644 --- a/src/Map/GroupBy.lua +++ b/src/Map/GroupBy.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Groups elements of a table by a key returned by the grouper function. The grouper function is passed the value and key of each element. --- Usage: GroupBy({A = 1, B = 2, C = 3}, function(Value, Key) return Value % 2 end) --> {[0] = {B = 2}, [1] = {A = 1, C = 3}} diff --git a/src/Map/IsMap.lua b/src/Map/IsMap.lua index 8f1e2ea..dd257d9 100644 --- a/src/Map/IsMap.lua +++ b/src/Map/IsMap.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Checks if the input table has a map / dictionary component. Not mutually exclusive to IsArray. local function IsMap(Structure: {[any]: any}): boolean diff --git a/src/Map/IsMixed.lua b/src/Map/IsMixed.lua index b7a9bb9..83498ad 100644 --- a/src/Map/IsMixed.lua +++ b/src/Map/IsMixed.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local IsMap = require(script.Parent:WaitForChild("IsMap")) local IsArray = require(script.Parent.Parent:WaitForChild("Array"):WaitForChild("IsArray")) diff --git a/src/Map/IsPureMap.lua b/src/Map/IsPureMap.lua index bfcdfac..8c8c611 100644 --- a/src/Map/IsPureMap.lua +++ b/src/Map/IsPureMap.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local IsArray = require(script.Parent.Parent:WaitForChild("Array"):WaitForChild("IsArray")) local IsMap = require(script.Parent:WaitForChild("IsMap")) diff --git a/src/Map/Keys.lua b/src/Map/Keys.lua index f015f0a..59a65b9 100644 --- a/src/Map/Keys.lua +++ b/src/Map/Keys.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Obtains the keys from a table. local function Keys(Structure: {[K]: any}): {K} diff --git a/src/Map/Lockdown.lua b/src/Map/Lockdown.lua index e668752..ab1ac59 100644 --- a/src/Map/Lockdown.lua +++ b/src/Map/Lockdown.lua @@ -1,5 +1,12 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict + +local LockedMetatable = { + __index = function(_, Key) + error(`Attempted to read key from a locked down table: {Key}`, 2) + end; +} --- Locks down a table, freezing it and further preventing any reads. local function Lockdown(Subject: any) @@ -7,12 +14,7 @@ local function Lockdown(Subject: any) Subject[Key] = nil end - setmetatable(Subject, { - __index = function(_, Key) - error(`Attempted to read key from a locked down table: {Key}`, 2) - end; - }) - + setmetatable(Subject, LockedMetatable) table.freeze(Subject) end diff --git a/src/Map/Map.lua b/src/Map/Map.lua index e72d139..ad780c2 100644 --- a/src/Map/Map.lua +++ b/src/Map/Map.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Puts each key-value pair in a table through a transformation function, mapping the outputs into a new table. local function Map(Structure: {[K]: V}, Operation: (V, K) -> (VT?, KT?)): {[KT | K]: VT} diff --git a/src/Map/Merge.lua b/src/Map/Merge.lua index b531996..bc75501 100644 --- a/src/Map/Merge.lua +++ b/src/Map/Merge.lua @@ -1,15 +1,23 @@ ---!optimize 2 --!native - -local MutableMerge = require(script.Parent:WaitForChild("MutableMerge")) +--!optimize 2 +--!nonstrict --- Merges two tables together, returning a new one. +--- Metatables are preserved, with new metatables overwrtiting old metatables. local function Merge(X: {[K1]: V1}, Y: {[K2]: V2}): {[K1 | K2]: V1 | V2} if (next(X) == nil) then + local MT = getmetatable(Y :: any) or getmetatable(X :: any) + if (MT) then + return setmetatable(table.clone(Y) :: any, MT) + end return Y end if (next(Y) == nil) then + local MT = getmetatable(Y :: any) -- or getmetatable(X :: any) + if (MT) then + return setmetatable(table.clone(X) :: any, MT) + end return X end @@ -17,6 +25,11 @@ local function Merge(X: {[K1]: V1}, Y: {[K2]: V2}): {[K1 | K2]: for Key, Value in Y do Result[Key] = Value end + + local MT = getmetatable(Y :: any) + if (MT) then + setmetatable(Result, MT) + end return Result end diff --git a/src/Map/Merge.spec.lua b/src/Map/Merge.spec.lua index 0c536bb..535c939 100644 --- a/src/Map/Merge.spec.lua +++ b/src/Map/Merge.spec.lua @@ -42,5 +42,46 @@ return function() expect(Result.Y).to.equal(3) expect(Result.Z).to.equal(4) end) + + it("should preserve left-side metatables when the right-side has no metatable", function() + local MT = {__len = function() end} + + -- With values inside. + local Result = Merge(setmetatable({Value1 = 1}, MT), {}) + expect(getmetatable(Result)).to.equal(MT) + + -- With no values inside. + Result = Merge(setmetatable({}, MT), {}) + expect(getmetatable(Result)).to.equal(MT) + end) + + it("should overwrite left-side metatables with right-side metatables", function() + local MT = {__len = function() end} + local MT2 = {__len = function() end} + + -- With values inside. + local Result = Merge(setmetatable({Value1 = 1}, MT), setmetatable({Value2 = 2}, MT2)) + expect(getmetatable(Result)).to.equal(MT2) + + -- With no values inside. + local X = setmetatable({}, MT) + local Y = setmetatable({}, MT2) + Result = Merge(X, Y) + expect(getmetatable(Result)).to.equal(MT2) + expect(Result).never.to.equal(X) + expect(Result).never.to.equal(Y) + end) + + it("should preserve right-side metatables when a new value is added", function() + local MT = {__len = function() end} + + -- With values inside. + local Result = Merge({Value1 = 1}, setmetatable({Value2 = 2}, MT)) + expect(getmetatable(Result)).to.equal(MT) + + -- With no values inside. + Result = Merge({}, setmetatable({}, MT)) + expect(getmetatable(Result)).to.equal(MT) + end) end) end \ No newline at end of file diff --git a/src/Map/MergeDeep.lua b/src/Map/MergeDeep.lua index 427f8a7..dee22f8 100644 --- a/src/Map/MergeDeep.lua +++ b/src/Map/MergeDeep.lua @@ -1,24 +1,39 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict ---- Creates a new data structure, representing the recursive merge of one table into another. Ensures structural sharing. -local function MergeDeep(Into: {[K1]: V1}, Data: {[K2]: V2}): {[K1 | K2]: V1 | V2} - if (next(Into) == nil) then - return Data +--- Creates a new data structure, representing the recursive merge of one table into another. +--- Metatables are preserved, with new metatables overwrtiting old metatables. +local function MergeDeep(X: {[K1]: V1}, Y: {[K2]: V2}): {[K1 | K2]: V1 | V2} + if (next(X) == nil) then + local MT = getmetatable(Y :: any) or getmetatable(X :: any) + if (MT) then + return setmetatable(table.clone(Y) :: any, MT) + end + return Y end - if (next(Data) == nil) then - return Into + if (next(Y) == nil) then + local MT = getmetatable(Y :: any) + if (MT) then + return setmetatable(table.clone(X) :: any, MT) + end + return X end - if (Into == Data) then - return Into + if (X == Y) then + return X end - local Result = table.clone(Into) - for Key, Value in Data do + local Result = table.clone(X) + for Key, Value in Y do Result[Key] = (type(Value) == "table" and MergeDeep(Result[Key] or {}, Value) or Value) end + + local MT = getmetatable(Y :: any) + if (MT) then + setmetatable(Result, MT) + end return Result end diff --git a/src/Map/MergeDeep.spec.lua b/src/Map/MergeDeep.spec.lua index e25f586..cb713db 100644 --- a/src/Map/MergeDeep.spec.lua +++ b/src/Map/MergeDeep.spec.lua @@ -101,5 +101,86 @@ return function() expect(Result).to.equal(X) expect(Result).to.equal(Y) end) + + it("should preserve left-side metatables when the right-side has no metatable", function() + local MT = {__len = function() end} + + -- With values inside. + local Result = MergeDeep({ + Test = { + Test = setmetatable({Value1 = 1}, MT); + }; + }, { + Test = { + Test = {Value2 = 2}; + }; + }) + expect(getmetatable(Result.Test.Test)).to.equal(MT) + + -- With no values inside. + Result = MergeDeep({ + Test = { + Test = setmetatable({}, MT); + }; + }, { + Test = { + Test = {}; + }; + }) + expect(getmetatable(Result.Test.Test)).to.equal(MT) + end) + + it("should overwrite left-side metatables with right-side metatables", function() + local MT = {__len = function() end} + local MT2 = {__len = function() end} + + -- With values inside. + local Result = MergeDeep({ + Test = { + Test = setmetatable({Value1 = 1}, MT); + }; + }, { + Test = { + Test = setmetatable({Value2 = 2}, MT2); + }; + }) + expect(getmetatable(Result.Test.Test)).to.equal(MT2) + + -- With no values inside. + local X = { + Test = { + Test = setmetatable({}, MT); + }; + } + local Y = { + Test = { + Test = setmetatable({}, MT2); + }; + } + Result = MergeDeep(X, Y) + expect(getmetatable(Result.Test.Test)).to.equal(MT2) + expect(Result.Test.Test).never.to.equal(X.Test) + expect(Result.Test.Test).never.to.equal(Y.Test) + end) + + it("should preserve right-side metatables when a new value is added", function() + local MT = {__len = function() end} + + -- With values inside. + local Result = MergeDeep({Value1 = 1}, { + Test = { + Test = setmetatable({Value2 = 2}, MT); + }; + }) + expect(getmetatable(Result.Test.Test)).to.equal(MT) + + -- With no values inside. + Result = MergeDeep({}, { + Test = { + Test = setmetatable({}, MT); + }; + }) + expect(getmetatable(Result.Test.Test)).to.equal(MT) + end) end) end \ No newline at end of file diff --git a/src/Map/MergeMany.lua b/src/Map/MergeMany.lua index c919cbd..140daa9 100644 --- a/src/Map/MergeMany.lua +++ b/src/Map/MergeMany.lua @@ -1,7 +1,9 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Merges various tables together. +--- Metatables are preserved, with new metatables overwrtiting old metatables. local function MergeMany(...) local Count = select("#", ...) if (Count == 0) then @@ -10,9 +12,15 @@ local function MergeMany(...) local Result = table.clone((select(1, ...))) for Index = 2, Count do - for Key, Value in (select(Index, ...)) do + local Table = (select(Index, ...)) + for Key, Value in Table do Result[Key] = Value end + + local MT = getmetatable(Table :: any) + if (MT) then + setmetatable(Result, MT) + end end return Result end diff --git a/src/Map/MergeMany.spec.lua b/src/Map/MergeMany.spec.lua index 3c93a18..5f1c522 100644 --- a/src/Map/MergeMany.spec.lua +++ b/src/Map/MergeMany.spec.lua @@ -37,5 +37,35 @@ return function() expect(Result.C).to.equal(3) expect(Result.D).to.equal(4) end) + + it("should allow left-hand metatables to be overwriten by right-hand metatables", function() + local MT1 = {__len = function() end} + local MT2 = {__len = function() end} + local MT3 = {__len = function() end} + + local Result = MergeMany( + setmetatable({A = 1}, MT1), + setmetatable({B = 2}, MT2), + setmetatable({C = 3}, MT3) + ) + + expect(Result).to.be.ok() + expect(Result).to.be.a("table") + expect(getmetatable(Result)).to.equal(MT3) + expect(Result.A).to.equal(1) + expect(Result.B).to.equal(2) + expect(Result.C).to.equal(3) + end) + + it("should preserve left-side metatables when right-side has no metatable", function() + local MT1 = {__len = function() end} + local Result = MergeMany( + setmetatable({Value1 = 1}, MT1), + {Value2 = 2} + ) + expect(getmetatable(Result)).to.equal(MT1) + expect(Result.Value1).to.equal(1) + expect(Result.Value2).to.equal(2) + end) end) end \ No newline at end of file diff --git a/src/Map/MutableMerge.lua b/src/Map/MutableMerge.lua index ae1d563..a52850c 100644 --- a/src/Map/MutableMerge.lua +++ b/src/Map/MutableMerge.lua @@ -1,11 +1,17 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Merges two tables together. +--- Metatables are preserved, with new metatables overwrtiting old metatables. local function MutableMerge(X: {[any]: any}, Y: {[any]: any}) for Key, Value in Y do X[Key] = Value end + local MT = getmetatable(Y :: any) + if (MT) then + setmetatable(X, MT) + end end return MutableMerge \ No newline at end of file diff --git a/src/Map/MutableMerge.spec.lua b/src/Map/MutableMerge.spec.lua index 90b9b27..aab755b 100644 --- a/src/Map/MutableMerge.spec.lua +++ b/src/Map/MutableMerge.spec.lua @@ -35,5 +35,22 @@ return function() expect(Result.A).to.equal(1) expect(Result.B).to.equal(false) end) + + it("should preserve a metatable on the left-side table with a non-metatable on the right-side table", function() + local MT = {__len = function() end} + local Left = setmetatable({A = 1, B = 2}, MT) + local Right = {C = 3, D = 4} + MutableMerge(Left, Right) + expect(getmetatable(Left)).to.equal(MT) + end) + + it("should overwrite a left-side metatable with a right-side metatable", function() + local MT = {__len = function() end} + local MT2 = {__len = function() end} + local Left = setmetatable({A = 1, B = 2}, MT) + local Right = setmetatable({C = 3, D = 4}, MT2) + MutableMerge(Left, Right) + expect(getmetatable(Left)).to.equal(MT2) + end) end) end \ No newline at end of file diff --git a/src/Map/MutableMergeDeep.lua b/src/Map/MutableMergeDeep.lua index a79aec9..4b16b01 100644 --- a/src/Map/MutableMergeDeep.lua +++ b/src/Map/MutableMergeDeep.lua @@ -1,21 +1,28 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict -local function MutableMergeDeep(Into, Data) - for Key, Value in Data do - if (type(Value) == "table") then - local Got = Into[Key] +--- Merges both given tables recursively. +--- Metatables are preserved, with new metatables overwrtiting old metatables. +local function MutableMergeDeep(X, Y) + local MT = getmetatable(Y :: any) + if (MT) then + setmetatable(X, MT) + end + for Key, Value in Y do + if (type(Value) == "table") then + local Got = X[Key] if (not Got) then Got = {} - Into[Key] = Got + X[Key] = Got end MutableMergeDeep(Got, Value) continue end - Into[Key] = Value + X[Key] = Value end end diff --git a/src/Map/MutableMergeDeep.spec.lua b/src/Map/MutableMergeDeep.spec.lua index 01c542a..68e57eb 100644 --- a/src/Map/MutableMergeDeep.spec.lua +++ b/src/Map/MutableMergeDeep.spec.lua @@ -43,5 +43,28 @@ return function() expect(Result.X).never.to.equal(MergeIn1.X) expect(Result.Y).never.to.equal(MergeIn2.Y) end) + + + + + + + + it("should preserve a metatable on the left-side table with a non-metatable on the right-side table", function() + local MT = {__len = function() end} + local Left = {Test = setmetatable({A = 1, B = 2}, MT)} + local Right = {Test = {C = 3, D = 4}} + MutableMergeDeep(Left, Right) + expect(getmetatable(Left.Test)).to.equal(MT) + end) + + it("should overwrite a left-side metatable with a right-side metatable", function() + local MT = {__len = function() end} + local MT2 = {__len = function() end} + local Left = {Test = setmetatable({A = 1, B = 2}, MT)} + local Right = {Test = setmetatable({C = 3, D = 4}, MT2)} + MutableMergeDeep(Left, Right) + expect(getmetatable(Left.Test)).to.equal(MT2) + end) end) end \ No newline at end of file diff --git a/src/Map/MutableMergeMany.lua b/src/Map/MutableMergeMany.lua index 6d213d7..5110fd6 100644 --- a/src/Map/MutableMergeMany.lua +++ b/src/Map/MutableMergeMany.lua @@ -1,20 +1,25 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local MutableMerge = require(script.Parent:WaitForChild("MutableMerge")) --- Merges various tables together. +--- Metatables are preserved, with new metatables overwrtiting old metatables. local function MutableMergeMany(...: {any}): {any} local Target = select(1, ...) for Index = 2, select("#", ...) do local Table = select(Index, ...) - if (not Table) then continue end - MutableMerge(Target, Table) + + local MT = getmetatable(Table :: any) + if (MT) then + setmetatable(Target, MT) + end end return Target diff --git a/src/Map/MutableMergeMany.spec.lua b/src/Map/MutableMergeMany.spec.lua index 9f96147..13e417f 100644 --- a/src/Map/MutableMergeMany.spec.lua +++ b/src/Map/MutableMergeMany.spec.lua @@ -35,5 +35,37 @@ return function() expect(Result.A).to.equal(1) expect(Result.B).to.equal(false) end) + + it("should allow left-hand metatables to be overwriten by right-hand metatables", function() + local MT1 = {__len = function() end} + local MT2 = {__len = function() end} + local MT3 = {__len = function() end} + + local Result = setmetatable({A = 1}, MT1) + MutableMergeMany( + Result, + setmetatable({B = 2}, MT2), + setmetatable({C = 3}, MT3) + ) + + expect(Result).to.be.ok() + expect(Result).to.be.a("table") + expect(getmetatable(Result)).to.equal(MT3) + expect(Result.A).to.equal(1) + expect(Result.B).to.equal(2) + expect(Result.C).to.equal(3) + end) + + it("should preserve left-side metatables when right-side has no metatable", function() + local MT1 = {__len = function() end} + local Result = setmetatable({Value1 = 1}, MT1) + MutableMergeMany( + Result, + {Value2 = 2} + ) + expect(getmetatable(Result)).to.equal(MT1) + expect(Result.Value1).to.equal(1) + expect(Result.Value2).to.equal(2) + end) end) end \ No newline at end of file diff --git a/src/Map/Removals.lua b/src/Map/Removals.lua index 6822dea..c3c7cb7 100644 --- a/src/Map/Removals.lua +++ b/src/Map/Removals.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Finds keys in X which are not in Y (i.e. removed values with respect to a base table). local function Removals(X: {[K]: V}, Y: {[K]: V}): {[K]: V} diff --git a/src/Map/SetUnresizable.lua b/src/Map/SetUnresizable.lua index 04691c4..8921d86 100644 --- a/src/Map/SetUnresizable.lua +++ b/src/Map/SetUnresizable.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict local PREVENT_WRITE_MT = { __newindex = function(_, Key) diff --git a/src/Map/InverseKeysValues.lua b/src/Map/SwapKeysValues.lua similarity index 72% rename from src/Map/InverseKeysValues.lua rename to src/Map/SwapKeysValues.lua index 7ed7dde..142cbab 100644 --- a/src/Map/InverseKeysValues.lua +++ b/src/Map/SwapKeysValues.lua @@ -1,8 +1,9 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Creates a new table with the keys and values swapped. Duplicate values will overwrite each other when swapped to keys. -local function InverseKeysValues(Structure: {[K]: V}): {[V]: K} +local function SwapKeysValues(Structure: {[K]: V}): {[V]: K} local Result = {} for Key, Value in Structure do Result[Value] = Key @@ -10,4 +11,4 @@ local function InverseKeysValues(Structure: {[K]: V}): {[V]: K} return Result end -return InverseKeysValues \ No newline at end of file +return SwapKeysValues \ No newline at end of file diff --git a/src/Map/InverseKeysValues.spec.lua b/src/Map/SwapKeysValues.spec.lua similarity index 68% rename from src/Map/InverseKeysValues.spec.lua rename to src/Map/SwapKeysValues.spec.lua index 2fc53ae..b938111 100644 --- a/src/Map/InverseKeysValues.spec.lua +++ b/src/Map/SwapKeysValues.spec.lua @@ -1,20 +1,20 @@ return function() - local InverseKeysValues = require(script.Parent.InverseKeysValues) + local SwapKeysValues = require(script.Parent.SwapKeysValues) - describe("Map/InverseKeysValues", function() + describe("Map/SwapKeysValues", function() it("should return a blank table for no data", function() - expect(next(InverseKeysValues({}))).never.to.be.ok() + expect(next(SwapKeysValues({}))).never.to.be.ok() end) it("should return a single flipped key-value pair for a single item table", function() - local Result = InverseKeysValues({X = "Y"}) + local Result = SwapKeysValues({X = "Y"}) expect(Result.Y).to.equal("X") expect(Result.X).never.to.be.ok() end) it("should return a flipped key-value pair for each item in the table", function() - local Result = InverseKeysValues({A = "P", B = "Q", C = "R"}) + local Result = SwapKeysValues({A = "P", B = "Q", C = "R"}) expect(Result.P).to.equal("A") expect(Result.Q).to.equal("B") diff --git a/src/Map/ToKeyValueArray.lua b/src/Map/ToKeyValueArray.lua index 3926943..9a80098 100644 --- a/src/Map/ToKeyValueArray.lua +++ b/src/Map/ToKeyValueArray.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Converts a table into an array of key-value objects. local function ToKeyValueArray(Structure: {[K]: V}): {{Key: K, Value: V}} diff --git a/src/Map/Values.lua b/src/Map/Values.lua index 3b1d46f..ff55cc5 100644 --- a/src/Map/Values.lua +++ b/src/Map/Values.lua @@ -1,5 +1,6 @@ ---!optimize 2 --!native +--!optimize 2 +--!nonstrict --- Obtains the values from a table. local function Values(Structure: {[any]: T}): {T} diff --git a/src/Map/init.lua b/src/Map/init.lua index f33a8cf..e680589 100644 --- a/src/Map/init.lua +++ b/src/Map/init.lua @@ -9,7 +9,6 @@ return { Flatten = require(script.Flatten); FromKeyValueArray = require(script.FromKeyValueArray); GroupBy = require(script.GroupBy); - InverseKeysValues = require(script.InverseKeysValues); IsMap = require(script.IsMap); IsMixed = require(script.IsMixed); IsPureMap = require(script.IsPureMap); @@ -24,6 +23,7 @@ return { MutableMergeMany = require(script.MutableMergeMany); Removals = require(script.Removals); SetUnresizable = require(script.SetUnresizable); + SwapKeysValues = require(script.SwapKeysValues); ToKeyValueArray = require(script.ToKeyValueArray); Values = require(script.Values); }; \ No newline at end of file diff --git a/src/Set/Difference.lua b/src/Set/Difference.lua index 51844d8..987d54c 100644 --- a/src/Set/Difference.lua +++ b/src/Set/Difference.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/Equals.lua b/src/Set/Equals.lua index 2349d74..1a92328 100644 --- a/src/Set/Equals.lua +++ b/src/Set/Equals.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/FromKeys.lua b/src/Set/FromKeys.lua index 47e6076..633a238 100644 --- a/src/Set/FromKeys.lua +++ b/src/Set/FromKeys.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/FromValues.lua b/src/Set/FromValues.lua index 2762fd5..73e6167 100644 --- a/src/Set/FromValues.lua +++ b/src/Set/FromValues.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/Insert.lua b/src/Set/Insert.lua index c1b2583..aab6149 100644 --- a/src/Set/Insert.lua +++ b/src/Set/Insert.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/Insert.spec.lua b/src/Set/Insert.spec.lua index c1f8e48..a496aaa 100644 --- a/src/Set/Insert.spec.lua +++ b/src/Set/Insert.spec.lua @@ -1,7 +1,7 @@ -local Set = require(script.Parent) -local Insert = require(script.Parent:FindFirstChild("Insert")) - return function() + local Set = require(script.Parent) + local Insert = require(script.Parent:FindFirstChild("Insert")) + describe("Set/Insert", function() it("should return the same set given a nil value", function() local Sample1 = Set({}) diff --git a/src/Set/Intersection.lua b/src/Set/Intersection.lua index 8571104..bc7a09e 100644 --- a/src/Set/Intersection.lua +++ b/src/Set/Intersection.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/IsProperSubset.lua b/src/Set/IsProperSubset.lua index 3707250..a898e27 100644 --- a/src/Set/IsProperSubset.lua +++ b/src/Set/IsProperSubset.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/IsSubset.lua b/src/Set/IsSubset.lua index 6328c3f..1fe1f51 100644 --- a/src/Set/IsSubset.lua +++ b/src/Set/IsSubset.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/Remove.lua b/src/Set/Remove.lua index 4a8969e..c3ac359 100644 --- a/src/Set/Remove.lua +++ b/src/Set/Remove.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/Remove.spec.lua b/src/Set/Remove.spec.lua index 4002d2a..479ab1a 100644 --- a/src/Set/Remove.spec.lua +++ b/src/Set/Remove.spec.lua @@ -1,7 +1,7 @@ -local Set = require(script.Parent) -local Remove = require(script.Parent:FindFirstChild("Remove")) - return function() + local Set = require(script.Parent) + local Remove = require(script.Parent:FindFirstChild("Remove")) + describe("Set/Remove", function() it("should return the same set given a nil value", function() local Sample1 = Set({}) diff --git a/src/Set/SymmetricDifference.lua b/src/Set/SymmetricDifference.lua index b5cff96..bd8125d 100644 --- a/src/Set/SymmetricDifference.lua +++ b/src/Set/SymmetricDifference.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/ToArray.lua b/src/Set/ToArray.lua index e87ff49..eab3f9d 100644 --- a/src/Set/ToArray.lua +++ b/src/Set/ToArray.lua @@ -1,15 +1,16 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set --- Converts a set of values to an array of those values. local function ToArray(Set: Set): {T} local Result = {} - for Key in Set do table.insert(Result, Key) end - return Result end diff --git a/src/Set/Union.lua b/src/Set/Union.lua index a666738..5d8ce2f 100644 --- a/src/Set/Union.lua +++ b/src/Set/Union.lua @@ -1,4 +1,7 @@ +--!native +--!optimize 2 --!nonstrict + local SetType = require(script.Parent:WaitForChild("_SetType")) type Set = SetType.Set diff --git a/src/Set/init.lua b/src/Set/init.lua index c073b4b..64217eb 100644 --- a/src/Set/init.lua +++ b/src/Set/init.lua @@ -11,7 +11,7 @@ local Result = { Intersection = require(script.Intersection); IsProperSubset = require(script.IsProperSubset); IsSubset = require(script.IsSubset); - Remove = require(script.Remove); + Remove = require(script:FindFirstChild("Remove")); SymmetricDifference = require(script.SymmetricDifference); ToArray = require(script.ToArray); Union = require(script.Union); diff --git a/src/_GenerateImports.lua b/src/_GenerateImports.lua deleted file mode 100644 index 83df91f..0000000 --- a/src/_GenerateImports.lua +++ /dev/null @@ -1,14 +0,0 @@ -local Result = {} - -for _, Module in game.Selection:Get()[1]:GetChildren() do - local Name = Module.Name - - if (Name == "init" or Name:match("%.spec") or Name:match("%_")) then - continue - end - - table.insert(Result, `{Name} = require(script:WaitForChild("{Name}"));`) -end - -table.sort(Result) -print(table.concat(Result, "\n")) \ No newline at end of file diff --git a/wally.toml b/wally.toml index a502b98..a89ce8b 100644 --- a/wally.toml +++ b/wally.toml @@ -1,6 +1,6 @@ [package] name = "tpc9000/tableutil" -version = "0.6.0" +version = "0.7.0" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" license = "MIT"