summaryrefslogtreecommitdiffstatshomepage
path: root/runtime/lua/vim/shared.lua
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2025-07-25 15:12:23 +0100
committerLewis Russell <me@lewisr.dev>2025-07-28 09:34:06 +0100
commitcf9b36f3d97b6f9c66ffff008bc1b5a5dd14ca98 (patch)
tree40a42c440a32af74a08bef9223c35643c157b833 /runtime/lua/vim/shared.lua
parent7a051a4c389452b4955c22e3c29071433e01905a (diff)
feat(lua): add vim.list.unique()
Problem: No way to deduplicate values in a list in-place Solution: Add `vim.list.unique()`
Diffstat (limited to 'runtime/lua/vim/shared.lua')
-rw-r--r--runtime/lua/vim/shared.lua56
1 files changed, 56 insertions, 0 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 9476654e37..ccf7674253 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -348,6 +348,62 @@ function vim.list_contains(t, value)
return false
end
+vim.list = {}
+
+--- Removes duplicate values from a list-like table in-place.
+---
+--- Only the first occurrence of each value is kept.
+--- The operation is performed in-place and the input table is modified.
+---
+--- Accepts an optional `hash` argument that if provided is called for each
+--- value in the list to compute a hash key for uniqueness comparison.
+--- This is useful for deduplicating table values or complex objects.
+---
+--- Example:
+--- ```lua
+---
+--- local t = {1, 2, 2, 3, 1}
+--- vim.list.unique(t)
+--- -- t is now {1, 2, 3}
+---
+--- local t = { {id=1}, {id=2}, {id=1} }
+--- vim.list.unique(t, function(x) return x.id end)
+--- -- t is now { {id=1}, {id=2} }
+--- ```
+---
+--- @generic T
+--- @param t T[]
+--- @param key? fun(x: T): any? Optional hash function to determine uniqueness of values
+--- @return T[] : The deduplicated list
+function vim.list.unique(t, key)
+ vim.validate('t', t, 'table')
+ local seen = {} --- @type table<any,boolean>
+
+ local finish = #t
+ key = key or function(a)
+ return a
+ end
+
+ local j = 1
+ for i = 1, finish do
+ local v = t[i]
+ local vh = key(v)
+ if not seen[vh] then
+ t[j] = v
+ if vh ~= nil then
+ seen[vh] = true
+ end
+ j = j + 1
+ end
+ end
+
+ for i = j, finish do
+ t[i] = nil
+ end
+
+ return t
+end
+
--- Checks if a table is empty.
---
---@see https://github.com/premake/premake-core/blob/master/src/base/table.lua