Skip to content

Commit

Permalink
feat(lib.iter): add index support to map
Browse files Browse the repository at this point in the history
This allows for mapping subsequent arrays into their inside values.

e.g.
```lua
iter.map(
  {
    { { foo = 1} }
  },
  1,
  'foo'
) ==  { 1 }
```
  • Loading branch information
Dich0tomy committed Dec 1, 2024
1 parent 72f81b5 commit 1018d5e
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions lua/cpp-tools/lib/iter/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
local M = {}

-- TODO: Use an iter mechanism instead of relying on tables everywhere

---Counts the lines in a string
---@param str string the string to count lines for
---@return number line count # The number of lines
Expand Down Expand Up @@ -62,10 +64,17 @@ function M.partition(range, pred, proj_beg)
vim.iter(range):map(proj_beg):filter(fp.nah(pred)):totable() or {}
end

---Maps a range using a function or a name of an internal field
-- TODO: Instead of using an overengineered map thingy
-- have a more robust vim.iter mechanism

---Maps a range using a function, index or a name of an internal field
---Using a function will map the current element using the function,
---Using a field name will do `vim.tbl_get(t, name)`
---Using an integer will do `t[idx]`
---e.g. `fp.map({ { foo = 1 } }, 1, 'foo', function(x) return x * 2 end)` will return { 2 }
---@generic T, U
---@param range [`T`] The range to partition
---@param ... string|fun(T): U Mapping functions or field names
---@param ... integer|string|fun(T): U Mapping functions or field names
---@return [U]|[any]
function M.map(range, ...)
local mappings = { ... }
Expand All @@ -81,10 +90,15 @@ function M.map(range, ...)
)

return vim.tbl_get(final, mapping)
elseif mapping_type == 'number' then
return final[mapping]
elseif mapping_type == 'function' then
return mapping(final)
else
assert(false, ('The type of mapping must be a function or a string, not [%s]'):format(mapping_type))
assert(
false,
('The type of mapping must be a function, a string or an integer, not [%s]'):format(mapping_type)
)
end
end)
end)
Expand Down Expand Up @@ -250,6 +264,7 @@ function M.__test()

assert.are.same(mapped, { 1, 3, 5, 7 })
end)

it('Maps using a single field name', function()
local arr = {
{ foo = 1, bar = 2 },
Expand All @@ -262,6 +277,7 @@ function M.__test()
assert.are.same(foos, { 1, 1, 1 })
assert.are.same(bars, { 2, 2, 2 })
end)

it('Maps nested tables', function()
local arr = {
{ foo = { bar = 1, qoox = { foox = 2, boox = 5 } } },
Expand All @@ -273,6 +289,7 @@ function M.__test()
assert.are.same(bars, { 1, 2 })
assert.are.same(fooxes, { 2, 1 })
end)

it('Maps with both functions and field names tables', function()
local arr = {
{ foo = { bar = 1, qoox = { foox = 2, boox = 5 } } },
Expand All @@ -284,6 +301,30 @@ function M.__test()

assert.are.same(bars, { 2, 4 })
end)

it('Maps using index', function()
local arr1 = {
{ { foo = 1, bar = 2 } },
{ { foo = 1, bar = 2 } },
}
local arr2 = {
{ foo = { 1, 2 } },
{ foo = { 1, 2 } },
}
local arr3 = {
{ { { { 'foo' } } } },
}

local mapped1 = M.map(arr1, 1, 'foo')
local mapped2 = M.map(arr2, 'foo', 2)
local mapped3 = M.map(arr3, 1, 1, 1, 1, function(s)
return ('%sbar'):format(s)
end)

assert.are.same(mapped1, { 1, 1 })
assert.are.same(mapped2, { 2, 2 })
assert.are.same(mapped3, { 'foobar' })
end)
end)
end

Expand Down

0 comments on commit 1018d5e

Please sign in to comment.