feat(runtime): accept predicates in take and skip (#34657)

Make `vim.iter():take()` and `vim.iter():skip()`
optionally accept predicates to enable takewhile
and skipwhile patterns used in functional
programming.
This commit is contained in:
Mart-Mihkel Aun
2025-07-03 16:12:24 +03:00
committed by GitHub
parent 715c28d67f
commit f01419f3d5
4 changed files with 149 additions and 13 deletions

View File

@@ -159,6 +159,30 @@ describe('vim.iter', function()
eq({}, vim.iter(q):skip(#q + 1):totable())
end
do
local function wrong()
return false
end
local function correct()
return true
end
local q = { 4, 3, 2, 1 }
eq({ 4, 3, 2, 1 }, vim.iter(q):skip(wrong):totable())
eq(
{ 2, 1 },
vim
.iter(q)
:skip(function(x)
return x > 2
end)
:totable()
)
eq({}, vim.iter(q):skip(correct):totable())
end
do
local function skip(n)
return vim.iter(vim.gsplit('a|b|c|d', '|')):skip(n):totable()
@@ -241,6 +265,14 @@ describe('vim.iter', function()
end)
it('take()', function()
local function correct()
return true
end
local function wrong()
return false
end
do
local q = { 4, 3, 2, 1 }
eq({}, vim.iter(q):take(0):totable())
@@ -251,6 +283,22 @@ describe('vim.iter', function()
eq({ 4, 3, 2, 1 }, vim.iter(q):take(5):totable())
end
do
local q = { 4, 3, 2, 1 }
eq({}, vim.iter(q):take(wrong):totable())
eq(
{ 4, 3 },
vim
.iter(q)
:take(function(x)
return x > 2
end)
:totable()
)
eq({ 4, 3, 2, 1 }, vim.iter(q):take(correct):totable())
end
do
local q = { 4, 3, 2, 1 }
eq({ 1, 2, 3 }, vim.iter(q):rev():take(3):totable())
@@ -271,6 +319,24 @@ describe('vim.iter', function()
-- non-array iterators are consumed by take()
eq({}, it:take(2):totable())
end
do
eq({ 'a', 'b', 'c', 'd' }, vim.iter(vim.gsplit('a|b|c|d', '|')):take(correct):totable())
eq(
{ 'a', 'b', 'c' },
vim
.iter(vim.gsplit('a|b|c|d', '|'))
:enumerate()
:take(function(i, x)
return i < 3 or x == 'c'
end)
:map(function(_, x)
return x
end)
:totable()
)
eq({}, vim.iter(vim.gsplit('a|b|c|d', '|')):take(wrong):totable())
end
end)
it('any()', function()