Skip to content

Commit

Permalink
Recycle names in map2() (#783)
Browse files Browse the repository at this point in the history
Closes #779
  • Loading branch information
lionel- committed Aug 27, 2022
1 parent df4630c commit 57aac14
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Expand Up @@ -11,6 +11,9 @@

## Features and fixes

* `map2()` and `pmap()` now recycle names of their first input if
needed (#783).

* `every()` now correctly propagates missing values using the same
rules as `&&` (#751). Internally, it has become a wrapper around
`&&`. This makes it consistent with `&&` and also with `some()`
Expand Down
14 changes: 10 additions & 4 deletions src/map.c
Expand Up @@ -7,14 +7,20 @@
#include "utils.h"

void copy_names(SEXP from, SEXP to) {
if (Rf_length(from) != Rf_length(to))
return;

SEXP names = Rf_getAttrib(from, R_NamesSymbol);
if (Rf_isNull(names))
if (names == R_NilValue) {
return;
}

R_len_t n = Rf_length(to);

if (Rf_length(names) != n) {
names = short_vec_recycle(names, n);
}
PROTECT(names);

Rf_setAttrib(to, R_NamesSymbol, names);
UNPROTECT(1);
}

void check_vector(SEXP x, const char *name) {
Expand Down
11 changes: 11 additions & 0 deletions tests/testthat/test-map2.R
Expand Up @@ -57,3 +57,14 @@ test_that("map2() with empty input copies names", {
expect_identical(map2_chr(named_list, list(), identity), named(chr()))
expect_identical(map2_raw(named_list, list(), identity), named(raw()))
})

test_that("map2() and pmap() recycle names (#779)", {
expect_identical(
map2(c(a = 1), 1:2, ~ .x),
list(a = 1, a = 1)
)
expect_identical(
pmap(list(c(a = 1), 1:2), ~ .x),
list(a = 1, a = 1)
)
})

0 comments on commit 57aac14

Please sign in to comment.