From 79d405208be143d4508851665bf7cfa1e19523df Mon Sep 17 00:00:00 2001
From: Cam <21029087+cxmeel@users.noreply.github.com>
Date: Tue, 12 Mar 2024 21:41:44 +0000
Subject: [PATCH] Refactor `Array.includes` and partial Dictionary
 reimplementation

---
 src/Array/includes.luau                       |  3 ++-
 src/Dictionary/copy.luau                      | 13 ++++++++++
 src/Dictionary/copyDeep.luau                  | 25 +++++++++++++++++++
 .../{copy.luau.todo => difference.luau.todo}  |  0
 ...uau.todo => differenceSymmetric.luau.todo} |  0
 src/Dictionary/flip.luau                      | 21 ++++++++++++++++
 src/Dictionary/flip.luau.todo                 |  0
 src/Dictionary/freeze.luau                    | 20 +++++++++++++++
 src/Dictionary/freeze.luau.todo               |  0
 src/Dictionary/get.luau                       | 24 ++++++++++++++++++
 src/Dictionary/has.luau                       | 14 +++++++++++
 src/Dictionary/has.luau.todo                  |  0
 src/Dictionary/includes.luau                  | 20 +++++++++++++++
 src/Dictionary/includes.luau.todo             |  0
 src/Dictionary/keys.luau                      | 20 +++++++++++++++
 src/Dictionary/keys.luau.todo                 |  0
 src/Dictionary/set.luau                       | 19 ++++++++++++++
 src/Dictionary/set.luau.todo                  |  0
 src/Dictionary/values.luau                    | 20 +++++++++++++++
 src/Dictionary/values.luau.todo               |  0
 20 files changed, 198 insertions(+), 1 deletion(-)
 create mode 100644 src/Dictionary/copy.luau
 create mode 100644 src/Dictionary/copyDeep.luau
 rename src/Dictionary/{copy.luau.todo => difference.luau.todo} (100%)
 rename src/Dictionary/{copyDeep.luau.todo => differenceSymmetric.luau.todo} (100%)
 create mode 100644 src/Dictionary/flip.luau
 delete mode 100644 src/Dictionary/flip.luau.todo
 create mode 100644 src/Dictionary/freeze.luau
 delete mode 100644 src/Dictionary/freeze.luau.todo
 create mode 100644 src/Dictionary/get.luau
 create mode 100644 src/Dictionary/has.luau
 delete mode 100644 src/Dictionary/has.luau.todo
 create mode 100644 src/Dictionary/includes.luau
 delete mode 100644 src/Dictionary/includes.luau.todo
 create mode 100644 src/Dictionary/keys.luau
 delete mode 100644 src/Dictionary/keys.luau.todo
 create mode 100644 src/Dictionary/set.luau
 delete mode 100644 src/Dictionary/set.luau.todo
 create mode 100644 src/Dictionary/values.luau
 delete mode 100644 src/Dictionary/values.luau.todo

diff --git a/src/Array/includes.luau b/src/Array/includes.luau
index e63b46d..76cee10 100644
--- a/src/Array/includes.luau
+++ b/src/Array/includes.luau
@@ -10,7 +10,8 @@ local find = require("./find")
     ```
 ]=]
 local function includes<T>(array: { T }, value: T, from: number?): boolean
-	return find(array, value, from) ~= nil
+	local index = find(array, value, from)
+	return index ~= nil
 end
 
 return includes
diff --git a/src/Dictionary/copy.luau b/src/Dictionary/copy.luau
new file mode 100644
index 0000000..490eae1
--- /dev/null
+++ b/src/Dictionary/copy.luau
@@ -0,0 +1,13 @@
+--[=[
+    @within Dictionary
+    @function copy
+    @param dictionary { [K]: V }
+    @return { [K]: V }
+
+    Returns a shallow copy of the dictionary. Use [Dictionary.copyDeep] to copy nested arrays.
+
+    ```lua
+    copy({ a = 1, b = 2 }) -- { a = 1, b = 2 }
+    ```
+]=]
+return table.clone
diff --git a/src/Dictionary/copyDeep.luau b/src/Dictionary/copyDeep.luau
new file mode 100644
index 0000000..772f1dd
--- /dev/null
+++ b/src/Dictionary/copyDeep.luau
@@ -0,0 +1,25 @@
+--[=[
+    @within Dictionary
+
+    Returns a deep copy of the given dictionary. This means that all nested tables are also copied.
+
+    ```lua
+    local dictionary = { a = 1, b = { c = 2 } }
+    copyDeep(dictionary) -- { a = 1, b = { c = 2 } }
+    ```
+]=]
+local function copyDeep<K, V>(dictionary: { [K]: V }): { [K]: V }
+	local out: { [K]: V } = {}
+
+	for key, value in dictionary do
+		if typeof(value) == "table" then
+			out[key] = copyDeep(value) :: any
+		else
+			out[key] = value
+		end
+	end
+
+	return out
+end
+
+return copyDeep
diff --git a/src/Dictionary/copy.luau.todo b/src/Dictionary/difference.luau.todo
similarity index 100%
rename from src/Dictionary/copy.luau.todo
rename to src/Dictionary/difference.luau.todo
diff --git a/src/Dictionary/copyDeep.luau.todo b/src/Dictionary/differenceSymmetric.luau.todo
similarity index 100%
rename from src/Dictionary/copyDeep.luau.todo
rename to src/Dictionary/differenceSymmetric.luau.todo
diff --git a/src/Dictionary/flip.luau b/src/Dictionary/flip.luau
new file mode 100644
index 0000000..f16dbfd
--- /dev/null
+++ b/src/Dictionary/flip.luau
@@ -0,0 +1,21 @@
+--[=[
+    @within Dictionary
+
+    Returns a new dictionary with the keys and values of the input dictionary swapped.
+
+    ```lua
+    local dictionary = { a = "apple", b = "banana" }
+    flip(dictionary) -- { apple = "a", banana = "b" }
+    ```
+]=]
+local function flip<K, V>(dictionary: { [K]: V }): { [V]: K }
+	local out = {}
+
+	for key, value in dictionary do
+		out[value] = key
+	end
+
+	return out
+end
+
+return flip
diff --git a/src/Dictionary/flip.luau.todo b/src/Dictionary/flip.luau.todo
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Dictionary/freeze.luau b/src/Dictionary/freeze.luau
new file mode 100644
index 0000000..254908e
--- /dev/null
+++ b/src/Dictionary/freeze.luau
@@ -0,0 +1,20 @@
+local copy = require("./copy")
+
+--[=[
+    @within Dictionary
+
+    Returns a new dictionary that is a shallow copy of the input dictionary, but is frozen. This means that the dictionary cannot be modified in any way. This is useful for ensuring that a dictionary is not modified after it has been created. Use [Dictionary.freezeDeep] to freeze a dictionary and all of its nested dictionaries.
+
+    ```lua
+    local frozen = freeze({ queen = "elsa", princess = "anna" })
+
+    frozen.princess = "elsa" -- error!
+    frozen.spirit = "bruni" -- error!
+    ```
+]=]
+local function freeze<K, V>(dictionary: { [K]: V }): { [K]: V }
+	local out = copy(dictionary)
+	return table.freeze(out)
+end
+
+return freeze
diff --git a/src/Dictionary/freeze.luau.todo b/src/Dictionary/freeze.luau.todo
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Dictionary/get.luau b/src/Dictionary/get.luau
new file mode 100644
index 0000000..205c9c7
--- /dev/null
+++ b/src/Dictionary/get.luau
@@ -0,0 +1,24 @@
+--[=[
+    @within Dictionary
+]=]
+local function get<K, V>(dictionary: { [K]: V }, key: K, dotSeparated: boolean?): V?
+	if not dotSeparated then
+		return dictionary[key]
+	end
+
+	local parts: { string } = (key :: any):split(".")
+	local value: any = dictionary
+
+	while #parts > 0 do
+		local part = table.remove(parts, 1)
+		value = value[part]
+
+		if value == nil then
+			return nil
+		end
+	end
+
+	return value
+end
+
+return get
diff --git a/src/Dictionary/has.luau b/src/Dictionary/has.luau
new file mode 100644
index 0000000..609e386
--- /dev/null
+++ b/src/Dictionary/has.luau
@@ -0,0 +1,14 @@
+--[=[
+    @within Dictionary
+
+    Returns whether the given dictionary contains the given key.
+
+    ```lua
+    has({ a = 1, b = 2 }, "a") -- true
+    ```
+]=]
+local function has<K, V>(dictionary: { [K]: V }, key: K): boolean
+	return dictionary[key] ~= nil
+end
+
+return has
diff --git a/src/Dictionary/has.luau.todo b/src/Dictionary/has.luau.todo
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Dictionary/includes.luau b/src/Dictionary/includes.luau
new file mode 100644
index 0000000..6205a7d
--- /dev/null
+++ b/src/Dictionary/includes.luau
@@ -0,0 +1,20 @@
+--[=[
+    @within Dictionary
+
+    Returns whether the dictionary includes a certain value or not. If the value is found, the function also returns the key associated with the value.
+
+    ```lua
+    includes({ a = 1, b = 3 }, 2) -- false
+    ```
+]=]
+local function includes<K, V>(dictionary: { [K]: V }, value: V): (boolean, K?)
+	for key, val in dictionary do
+		if val == value then
+			return true, key
+		end
+	end
+
+	return false, nil
+end
+
+return includes
diff --git a/src/Dictionary/includes.luau.todo b/src/Dictionary/includes.luau.todo
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Dictionary/keys.luau b/src/Dictionary/keys.luau
new file mode 100644
index 0000000..f9a165a
--- /dev/null
+++ b/src/Dictionary/keys.luau
@@ -0,0 +1,20 @@
+--[=[
+    @within Dictionary
+
+    Returns an array of all the keys in a dictionary.
+
+    ```lua
+    keys({ a = 1, b = 2, c = 3 }) -- { "a", "b", "c" }
+    ```
+]=]
+local function keys<K, V>(dictionary: { [K]: V }): { K }
+	local out = {}
+
+	for key in dictionary do
+		table.insert(out, key)
+	end
+
+	return out
+end
+
+return keys
diff --git a/src/Dictionary/keys.luau.todo b/src/Dictionary/keys.luau.todo
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Dictionary/set.luau b/src/Dictionary/set.luau
new file mode 100644
index 0000000..272109b
--- /dev/null
+++ b/src/Dictionary/set.luau
@@ -0,0 +1,19 @@
+local copy = require("./copy")
+
+--[=[
+    @within Dictionary
+
+    Returns a new dictionary with the given key set to the given value.
+
+    ```lua
+    set({ a = 1 }, "b", 2) -- { a = 1, b = 2 }
+    ```
+]=]
+local function set<K, V>(dictionary: { [K]: V }, key: K, value: V): { [K]: V }
+	local out = copy(dictionary)
+	out[key] = value
+
+	return out
+end
+
+return set
diff --git a/src/Dictionary/set.luau.todo b/src/Dictionary/set.luau.todo
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Dictionary/values.luau b/src/Dictionary/values.luau
new file mode 100644
index 0000000..da5a86e
--- /dev/null
+++ b/src/Dictionary/values.luau
@@ -0,0 +1,20 @@
+--[=[
+    @within Dictionary
+
+    Returns an array of all the values in a dictionary.
+
+    ```lua
+    values({ a = 1, b = 2, c = 3 }) -- { 1, 2, 3 }
+    ```
+]=]
+local function values<K, V>(dictionary: { [K]: V }): { V }
+	local out = {}
+
+	for _, value in dictionary do
+		table.insert(out, value)
+	end
+
+	return out
+end
+
+return values
diff --git a/src/Dictionary/values.luau.todo b/src/Dictionary/values.luau.todo
deleted file mode 100644
index e69de29..0000000