Skip to content

Implement str_like() closes #280#315

Merged
hadley merged 6 commits into
tidyverse:masterfrom
rjpat:master
Nov 11, 2019
Merged

Implement str_like() closes #280#315
hadley merged 6 commits into
tidyverse:masterfrom
rjpat:master

Conversation

@rjpat
Copy link
Copy Markdown
Contributor

@rjpat rjpat commented Nov 5, 2019

Created a str_like() function to match the SQL operator's wild cards and escaping. Works by converting the SQL version to their regex equivalents.
Closes #280

@rjpat rjpat mentioned this pull request Nov 5, 2019
Comment thread R/detect.r Outdated
fixed = stri_detect_fixed(string, pattern, negate = negate, opts_fixed = opts(pattern)),
coll = stri_detect_coll(string, pattern, negate = negate, opts_collator = opts(pattern)),
regex = {
pattern2 <- stri_replace_all_regex(pattern, "(?<!\\\\|\\[)%(?!\\])", "\\.\\*")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd recommend pulling this out into a separate function. Then it will be easier to test, and str_like() can become a thinner wrapper around str_detect()

@rjpat
Copy link
Copy Markdown
Contributor Author

rjpat commented Nov 7, 2019

Split the conversion into its own function and test set.

Copy link
Copy Markdown
Member

@hadley hadley left a comment

Choose a reason for hiding this comment

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

Looking good — a few more suggestions below.

Comment thread R/detect.r Outdated
#'
#' @examples
#' like_converter("bana%")
#' like_converter("app_e")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You don't need to document this function because it's not exported; and generally I think it's better to put little helper functions like this at the bottom of the file (so you see the big picture first, before the details)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And I think like_to_regex would be a slightly better name.

Comment thread R/detect.r Outdated
#' str_like(fruit, "ba_ana")
#' str_like(fruit, "%APPLE")
str_like <- function(string, pattern, negate = FALSE, ignore_case = TRUE) {
switch(type(pattern),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you could now simplify this to:

if (type(pattern) == "regex") {
  pattern <- like_converter(pattern)
}
str_detect(string, pattern, negate = negate, ignore_case = ignore_case)

Does that make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmmm, or should this function accept the other pattern types at all? Maybe that doesn't make sense for a more specialised function. In that case the function would look more like:

switch(type(pattern), 
  regex = stri_detect_regex(string, like_converter(pattern), negate = negate, opts_regex = opts(pattern)),
  stop("str_like() works only with regular expressions", call. = FALSE
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree that this should probably just accept a regex, have updated similar to above and made a separate call in order to preserve the ignore case earlier.

Comment thread tests/testthat/test-detect.r Outdated
})

test_that("str_like works", {
expect_true(str_like("abc", "a_c"))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Once you've rewritten str_like() as I suggested above you'll be able to substantially simplify this test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Have kept only one of the general test for str_like() as we are testing the like_to_regex converter earlier. Do you think there is any further way to simplify/should there be a test to ensure it fails on any other type of regex now?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I decided there was a slightly better way to check pattern so I tweaked the test too

@hadley hadley merged commit 80aaaac into tidyverse:master Nov 11, 2019
@hadley
Copy link
Copy Markdown
Member

hadley commented Nov 11, 2019

Thanks for all your hard work on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement str_like()

2 participants