diff --git a/crates/nu-std/std/mod.nu b/crates/nu-std/std/mod.nu index 9ac30ec869..395d5b0393 100644 --- a/crates/nu-std/std/mod.nu +++ b/crates/nu-std/std/mod.nu @@ -294,3 +294,33 @@ Startup Time: ($nu.startup-time) export def pwd [] { $env.PWD } + +# repeat anything a bunch of times, yielding a list of *n* times the input +# +# # Examples +# repeat a string +# > "foo" | std repeat 3 | str join +# "foofoofoo" +export def repeat [ + n: int # the number of repetitions, must be positive +]: any -> list { + let item = $in + + if $n < 0 { + let span = metadata $n | get span + error make { + msg: $"(ansi red_bold)invalid_argument(ansi reset)" + label: { + text: $"n should be a positive integer, found ($n)" + start: $span.start + end: $span.end + } + } + } + + if $n == 0 { + return [] + } + + ..($n - 1) | each { $item } +} diff --git a/crates/nu-std/tests/test_std.nu b/crates/nu-std/tests/test_std.nu index fcbc00fa48..6e82335aeb 100644 --- a/crates/nu-std/tests/test_std.nu +++ b/crates/nu-std/tests/test_std.nu @@ -44,3 +44,14 @@ def path_add [] { def banner [] { std assert ((std banner | lines | length) == 15) } + +#[test] +def repeat_things [] { + std assert error { "foo" | std repeat -1 } + + for x in ["foo", [1 2], {a: 1}] { + std assert equal ($x | std repeat 0) [] + std assert equal ($x | std repeat 1) [$x] + std assert equal ($x | std repeat 2) [$x $x] + } +}