You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I frequently have to sandwich/surround a string with either one (e.g. making the string hello into "hello") or two different placeholders (e.g. making the string hello into <hello>).
Would you consider adding a function that does this to stringr? It could possibly be called str_sandwich(). I imagine you can make a faster version and probably come up with a better name.
Here are two different approaches I've used to accomplish this with slightly different properties for reference.
Approach 1
Approach 1 uses paste. It is faster and always adds the placeholders to the strings, even when they are already there. It can optionally collapse output like paste (but I think it probably shouldn't be able to).
Function
#' Sandwich Text Between Placeholders#'#' Sandwiches strings between one or two placeholders.#'#' @param x A string or character vector.#' @param placeholder One or two placeholders to sandwich each element of `x`#' between. When two placeholders are provided, `x` will be sandwiched#' between them with the first on the left and second on the right.#' Otherwise, `x` will be sandwiched on both sides by the same placeholder.#' @inheritDotParams base::paste0#'#' @examples#' str_sandwich("a", placeholder = "h")#' str_sandwich("a", placeholder = c("b", "h"))#'#' @family general utilities#' @exportstr_sandwich<-function(x, placeholder, ...) {
if (length(placeholder) <1||
length(placeholder) >2||!is.character(placeholder)
) {
stop("`placeholder` must be a length-1 or -2 character vector.")
}
if (length(placeholder) ==1) {
out<- paste0(placeholder, x, placeholder, ...)
} else {
out<- paste0(placeholder[1], x, placeholder[2], ...)
}
if (!is.null(names(x))) {
names(out) <- names(x)
}
out
}
Approach 2 includes the option to avoid adding placeholders if they already exist at the start/end, as specified. It is slower because it uses stringr::str_replace() twice (stringr::str_replace_all() doesn't work for the optional case).
Function
#' Sandwich Text Between Placeholders#'#' Sandwiches strings between one or two placeholders.#'#' @param x A character vector.#' @param placeholder One or two placeholders to sandwich each element of `x`#' between. When two placeholders are provided, `x` will be sandwiched#' between them with the first at the start and second at the end.#' Otherwise, `x` will be sandwiched at both start and end by the same#' placeholder.#' @param add_dup Whether to add placeholders even if the same character is#' already found in that position, as a boolean (default: `TRUE`).#'#' @examples#' str_sandwich("a", placeholder = "h")#' str_sandwich("a", placeholder = c("b", "h"))#' str_sandwich("bah", placeholder = c("b", "h"), add_dup = TRUE)#' str_sandwich("bah", placeholder = c("b", "h"), add_dup = FALSE)#' str_sandwich("bah", placeholder = "h", add_dup = FALSE)#'#' @export#' Sandwich Text Between Placeholders#'#' Sandwiches strings between one or two placeholders.#'#' @param x A string or character vector.#' @param placeholder One or two placeholders to sandwich each element of `x`#' between. When two placeholders are provided, `x` will be sandwiched#' between them with the first at the start and second at the end.#' Otherwise, `x` will be sandwiched at both start and end by the same#' placeholder.#' @param add_dup Whether to add placeholders even if the same character is#' already found in that position, as a boolean (default: `TRUE`).#'#' @examples#' str_sandwich("a", placeholder = "h")#' str_sandwich("a", placeholder = c("b", "h"))#' str_sandwich("bah", placeholder = c("b", "h"), add_dup = TRUE)#' str_sandwich("bah", placeholder = c("b", "h"), add_dup = FALSE)#' str_sandwich("bah", placeholder = "h", add_dup = FALSE)#'#' @family general utilities#' @exportstr_sandwich<-function(x, placeholder, add_dup=TRUE) {
if (length(placeholder) <1||
length(placeholder) >2||!is.character(placeholder)
) {
stop("`placeholder` must be a length-1 or -2 character vector.")
}
placeholder2<- rep(placeholder, length(placeholder) %%2+1)
if (add_dup) {
pattern<- c("^", "$")
} else {
opt_placeholder<- paste0(placeholder2, "?")
pattern<- paste0(c("^", opt_placeholder[2]), c(opt_placeholder[1], "$"))
}
out<-stringr::str_replace(x, pattern[1], placeholder2[1])
out<-stringr::str_replace(out, pattern[2], placeholder2[2])
if (!is.null(names(x))) {
names(out) <- names(x)
}
out
}
Thanks for filing this issue! Unfortunately, I think it's a bit too special purpose for stringr since it doesn't reduce code that much compared to use paste() directly, and developing good software requires relentless focus, which means that we have to say no to many good ideas. Even though I'm closing this issue, I really appreciate the feedback, and hope you'll continue to contribute in the future 😄
I frequently have to sandwich/surround a string with either one (e.g. making the string
hello
into"hello"
) or two different placeholders (e.g. making the stringhello
into<hello>
).Would you consider adding a function that does this to stringr? It could possibly be called
str_sandwich()
. I imagine you can make a faster version and probably come up with a better name.Here are two different approaches I've used to accomplish this with slightly different properties for reference.
Approach 1
Approach 1 uses
paste
. It is faster and always adds the placeholders to the strings, even when they are already there. It can optionally collapse output likepaste
(but I think it probably shouldn't be able to).Function
Tests
Approach 2
Approach 2 includes the option to avoid adding placeholders if they already exist at the start/end, as specified. It is slower because it uses
stringr::str_replace()
twice (stringr::str_replace_all()
doesn't work for the optional case).Function
Tests
The text was updated successfully, but these errors were encountered: