purrr icon indicating copy to clipboard operation
purrr copied to clipboard

Feature Proposal: Recursive option for discard()

Open datawookie opened this issue 2 years ago • 0 comments

Hi!

I've just discovered the discard() function and I'm so thrilled: I do this sort of thing all the time and had to keep on coding this logic up manually.

However, I have a few applications where I would like to discard recursively. This is what I mean:

test <- list(
  x = 5,
  y = list(
    a = "foo",
    b = NULL,
    c = "bar"
  ),
  z = 7
)

discard(test, is.null)

I would like to be able to discard the b element in the nested list.

In order not to break existing functionality I'd propose a recursive argument (for consistency with the recursive argument in unlist()). The implementation would be something like this:

discard <- function(.x, .p, recursive = FALSE, ...) {
  .x <- purrr::discard(.x, .p, ...)
  if (recursive && is.list(.x)) {
    map(.x, function(x) discard(x, .p, TRUE, ...))
  } else {
    .x
  }
}

This would replicate existing behaviour.

> discard(test, is.null, recursive = FALSE)
$x
[1] 5

$y
$y$a
[1] "foo"

$y$b
NULL

$y$c
[1] "bar"


$z
[1] 7

But it would also allow for recursive discard()-ing like this:

> discard(test, is.null, recursive = TRUE)
$x
[1] 5

$y
$y$a
[1] "foo"

$y$c
[1] "bar"


$z
[1] 7

If you are agreeable to this idea then I'd be happy to code up a robust implementation and submit a PR.

Thanks for a magical package!

Best regards, Andrew.

datawookie avatar Aug 10 '22 08:08 datawookie