Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stevedonovan/Penlight.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Schreijer <thijs@thijsschreijer.nl>2022-01-13 22:04:26 +0300
committerThijs Schreijer <thijs@thijsschreijer.nl>2022-02-13 11:42:34 +0300
commit4ea8daeb7478487ff32a03d97d5ded16785018d8 (patch)
tree401f70de71c14b032bdbd3707e7b978566cef93c
parente738aa8b6c87ed8ed89128ad31849f216c575e0d (diff)
feat(utils) add 'kpairs' iterator
Iterates over all non-integer keys (inverse of 'ipairs'
-rw-r--r--CHANGELOG.md3
-rw-r--r--lua/pl/utils.lua43
-rw-r--r--spec/utils-kpairs_spec.lua38
3 files changed, 84 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b3385f0..8a4f1a1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,9 @@ see [CONTRIBUTING.md](CONTRIBUTING.md#release-instructions-for-a-new-version) fo
[#414](https://github.com/lunarmodules/Penlight/pull/414)
=======
- feat: `utils.enum` now accepts hash tables, to enable better error handling
+ [#413](https://github.com/lunarmodules/Penlight/pull/413)
+ - feat: `utils.kpairs` new iterator over all non-integer keys
+ [#413](https://github.com/lunarmodules/Penlight/pull/413)
>>>>>>> b38c390 (feat(utils) enum to accept hash tables as well)
diff --git a/lua/pl/utils.lua b/lua/pl/utils.lua
index d56a6ef..fed880c 100644
--- a/lua/pl/utils.lua
+++ b/lua/pl/utils.lua
@@ -13,6 +13,8 @@ local concat = table.concat
local _unpack = table.unpack -- always injected by 'compat'
local find = string.find
local sub = string.sub
+local next = next
+local floor = math.floor
local is_windows = compat.is_windows
local err_mode = 'default'
@@ -223,6 +225,47 @@ end
+--- an iterator over all non-integer keys (inverse of `ipairs`).
+-- It will skip any key that is an integer number, so negative indices or an
+-- array with holes will not return those either (so it returns slightly less than
+-- 'the inverse of `ipairs`').
+--
+-- This uses `pairs` under the hood, so any value that is iterable using `pairs`
+-- will work with this function.
+-- @tparam table t the table to iterate over
+-- @treturn key
+-- @treturn value
+-- @usage
+-- local t = {
+-- "hello",
+-- "world",
+-- hello = "hallo",
+-- world = "Welt",
+-- }
+--
+-- for k, v in utils.kpairs(t) do
+-- print("German: ", v)
+-- end
+--
+-- -- output;
+-- -- German: hallo
+-- -- German: Welt
+function utils.kpairs(t)
+ local index
+ return function()
+ local value
+ while true do
+ index, value = next(t, index)
+ if type(index) ~= "number" or floor(index) ~= index then
+ break
+ end
+ end
+ return index, value
+ end
+end
+
+
+
--- Error handling
-- @section Error-handling
diff --git a/spec/utils-kpairs_spec.lua b/spec/utils-kpairs_spec.lua
new file mode 100644
index 0000000..7fac079
--- /dev/null
+++ b/spec/utils-kpairs_spec.lua
@@ -0,0 +1,38 @@
+local utils = require("pl.utils")
+
+describe("pl.utils", function ()
+
+ describe("kpairs", function ()
+ local kpairs
+
+ before_each(function()
+ kpairs = utils.kpairs
+ end)
+
+
+ it("iterates over non-integers", function()
+ local func = function() end
+ local bool = true
+ local string = "a string"
+ local float = 123.45
+ local r = {}
+ for k, v in kpairs {
+ [func] = 1,
+ [bool] = 2,
+ [string] = 3,
+ [float] = 4,
+ 5, 6, 7,
+ } do
+ r[k] = v
+ end
+
+ assert.same({
+ [func] = 1,
+ [bool] = 2,
+ [string] = 3,
+ [float] = 4 }, r)
+ end)
+
+ end)
+
+end)