Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add sep argument to str_dup #564

Merged
merged 14 commits into from
Aug 20, 2024
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# stringr (development version)

* Add `sep` argument to `str_dup()` so that it is possible to repeat a string and
add a separator between every repeated value (@edward-burn, #564).

* Adds `[[.stringr_pattern` method to go along with existing `[.stringr_pattern`
method (@edward-burn, #569).

Expand Down
15 changes: 12 additions & 3 deletions R/dup.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@
#'
#' @inheritParams str_detect
#' @param times Number of times to duplicate each string.
#' @param sep String to insert between each duplicate.
#' @return A character vector the same length as `string`/`times`.
#' @export
#' @examples
#' fruit <- c("apple", "pear", "banana")
#' str_dup(fruit, 2)
#' str_dup(fruit, 1:3)
#' str_c("ba", str_dup("na", 0:5))
str_dup <- function(string, times) {
vctrs::vec_size_common(string = string, times = times)
stri_dup(string, times)
str_dup <- function(string, times, sep = NULL) {
input <- vctrs::vec_recycle_common(string = string, times = times)
check_string(sep, allow_null = TRUE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to move the other input check up here so that all the input checks are together.


if (is.null(sep)) {
stri_dup(input$string, input$times)
} else {
map_chr(seq_along(input$string), function(i) {
paste(rep(string[i], input$times[i]), collapse = sep)
})
}
}
4 changes: 3 additions & 1 deletion man/str_dup.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions tests/testthat/_snaps/dup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# separator must be a single string

Code
str_dup("a", 3, sep = 1)
Condition
Error in `str_dup()`:
! `sep` must be a single string or `NULL`, not the number 1.
Code
str_dup("a", 3, sep = c("-", ";"))
Condition
Error in `str_dup()`:
! `sep` must be a single string or `NULL`, not a character vector.

18 changes: 18 additions & 0 deletions tests/testthat/test-dup.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,21 @@ test_that("0 duplicates equals empty string", {
test_that("uses tidyverse recycling rules", {
expect_error(str_dup(1:2, 1:3), class = "vctrs_error_incompatible_size")
})

test_that("uses sep argument", {
expect_equal(str_dup("abc", 1, sep = "-"), "abc")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to make it a bit more clear was different in each test by keeping more stuff the same.

expect_equal(str_dup("abc", 2, sep = "-"), "abc-abc")

expect_equal(str_dup(c("a", "b"), 2, sep = "-"), c("a-a", "b-b"))
expect_equal(str_dup(c("a", "b"), c(1, 2), sep = "-"), c("a", "b-b"))

expect_equal(str_dup(character(), 1, sep = ":"), character())
expect_equal(str_dup(character(), 2, sep = ":"), character())
})

test_that("separator must be a single string", {
expect_snapshot(error = TRUE, {
str_dup("a", 3, sep = 1)
str_dup("a", 3, sep = c("-", ";"))
})
})
Loading