Last active
April 28, 2024 15:42
-
-
Save royratcliffe/12d74d27df1d38e2c2350c8a610a1cf8 to your computer and use it in GitHub Desktop.
Unique Lua Pairs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- Unique pairs. | |
-- @module uniq | |
-- @author Roy Ratcliffe <[email protected]> | |
-- @copyright 2023, 2024 | |
-- @license MIT | |
local _M = {} | |
local unpack = table.unpack or unpack -- Lua 5.1 compatibility | |
--- Answers the next index and unique value. | |
-- See [Semantics of the Generic `for`](https://www.lua.org/pil/7.2.html) for | |
-- details. | |
-- @tparam {{any,...},{[any]=bool}} forinvar For-loop invariant. | |
-- @tparam int forvar For-loop variant. | |
-- @treturn int Current index. | |
-- @treturn any Current unique value. | |
local function inext(forinvar, forvar) | |
local values, matched = unpack(forinvar) | |
local value | |
repeat | |
forvar = forvar + 1 | |
value = values[forvar] | |
if value == nil then return end | |
until not matched[value] | |
matched[value] = true | |
return forvar, value | |
end | |
--- Iterates unique values in an array. | |
-- Skips duplicates. The implementation utilises a table by up-value reference. | |
-- Unique `pairs` does not make sense. Index-value pairs automatically have the | |
-- unique index property. | |
-- @tparam {any,...} Array of any values. | |
-- @treturn func Iterator function. | |
-- @treturn {{any,...},{[any]=bool}} Tuple of values and matches. | |
-- @treturn number Initial array index. | |
function _M.ipairs(values) | |
return inext, { values, {} }, 0 | |
end | |
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe("uniq", function() | |
local UNIQ = require "uniq" | |
it("works", function() | |
local actual = {} | |
for index, value in UNIQ.ipairs { "a", "a", 1, 2, 3, 3 } do | |
table.insert(actual, { index, value }) | |
end | |
assert.are.same({ | |
{ 1, "a" }, | |
{ 3, 1 }, | |
{ 4, 2 }, | |
{ 5, 3 }, | |
}, actual) | |
end) | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment