From f555ba451ed9d5fb5fc0390fa445cee82cb0a388 Mon Sep 17 00:00:00 2001 From: edward-burn <9583964+edward-burn@users.noreply.github.com> Date: Thu, 15 Aug 2024 19:21:43 +0100 Subject: [PATCH] add sep argument to str_dup closes #487 Adds a sep argument to str_dup. Becasue this is not supported by stri_dup, do separately and use lapply to go through strings. --- R/dup.R | 19 +++++++++++++++++-- man/str_dup.Rd | 4 +++- tests/testthat/test-dup.R | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/R/dup.R b/R/dup.R index d90e62fb..c9f6f8fe 100644 --- a/R/dup.R +++ b/R/dup.R @@ -5,6 +5,7 @@ #' #' @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 @@ -12,7 +13,21 @@ #' str_dup(fruit, 2) #' str_dup(fruit, 1:3) #' str_c("ba", str_dup("na", 0:5)) -str_dup <- function(string, times) { +str_dup <- function(string, times, sep = NULL) { vctrs::vec_size_common(string = string, times = times) - stri_dup(string, times) + if(is.null(sep)){ + stri_dup(string, times) + } else { + # stri_dup does not currently support sep + check_string(sep) + lapply(seq_along(string), function(i) { + if (length(times) == 1) { + paste(rep(string[i], times), collapse = sep) + } else { + paste(rep(string[i], times[i]), collapse = sep) + } + }) |> + rlang::flatten_chr() + } + } diff --git a/man/str_dup.Rd b/man/str_dup.Rd index fb722f2c..a2e2e162 100644 --- a/man/str_dup.Rd +++ b/man/str_dup.Rd @@ -4,13 +4,15 @@ \alias{str_dup} \title{Duplicate a string} \usage{ -str_dup(string, times) +str_dup(string, times, sep = NULL) } \arguments{ \item{string}{Input vector. Either a character vector, or something coercible to one.} \item{times}{Number of times to duplicate each string.} + +\item{sep}{String to insert between each duplicate.} } \value{ A character vector the same length as \code{string}/\code{times}. diff --git a/tests/testthat/test-dup.R b/tests/testthat/test-dup.R index 2872ae37..108a0307 100644 --- a/tests/testthat/test-dup.R +++ b/tests/testthat/test-dup.R @@ -13,3 +13,20 @@ 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("a", 3, sep = ";"), "a;a;a") + expect_equal(str_dup("abc", 2, sep = "-"), "abc-abc") + expect_equal(str_dup("a", 3, sep = ";"), "a;a;a") + expect_equal(str_dup("abc", 2, sep = "-"), "abc-abc") + expect_equal(str_dup(c("a", "b"), 2, sep = "x"), c("axa", "bxb")) + expect_equal(str_dup(c("aa", "bb", "ccc"), c(2, 3, 4), sep = ";"), + c("aa;aa", "bb;bb;bb", "ccc;ccc;ccc;ccc")) + + expect_error(str_dup("a", 3, sep = 1)) + expect_error(str_dup("a", 3, sep = c("-", ";"))) + expect_error(str_dup(c("aa", "bb"), c(2, 3, 4), sep = ";")) + expect_error(str_dup(c("aa", "bb", "cc"), c(2, 3), sep = ";")) + +}) +