Rcpp 中字符串与单个值的矢量化比较

vectorised comparison of strings to single value in Rcpp

Rcpp 中的 == 运算符在将数值向量与单个值进行比较时按预期工作。 IE。将向量的每个元素与值进行比较,并返回一个逻辑向量。例如,考虑以下行为符合预期的行为:

library(Rcpp)
cppFunction('
CharacterVector test_vals(NumericVector x) {
  if (is_true(any(x == 3))) return ("Values include 3");
  return ("3 not found");
}')
test_vals(1:2)
# [1] "3 not found"
test_vals(1:5)
# [1] "Values include 3"

但是,如果我尝试将字符向量与字符标量进行比较,它似乎只测试了向量的第一个元素:

cppFunction('
CharacterVector test_names(NumericVector x) {
  CharacterVector y = x.attr("names");
  if (is_true(any(y == CharacterVector::create("foo")))) return ("Names include foo");
  return ("foo not found");
}')
test_names(c(a=1, b=2, foo=3))
# [1] "foo not found"
test_names(c(foo=3, a=1, b=2))
# [1] "Names include foo"

我知道比较两个相同长度的字符向量似乎以向量化的方式工作,正如预期的那样:

cppFunction('
CharacterVector test_names(NumericVector x) {
  CharacterVector y = x.attr("names");
  CharacterVector foo(x.size());
  foo.fill("foo");
  if (is_true(any(y == foo))) return ("Names include foo");
  return ("foo not found");
}')
test_names(c(a=1, b=2, foo=3))
# [1] "Names include foo"
test_names(c(foo=3, a=1, b=2))
# [1] "Names include foo"
test_names(c(a=1, b=2))
# [1] "foo not found"

这是否意味着字符向量与单个值的比较尚未在 Rcpp 中实现,或者我只是不知道如何做?

在我们的快速讨论之后,这里有一个非常简单的解决方案,因为问题(提出的)很简单——没有正则表达式,没有花哨的东西。只需遍历所有元素并在找到匹配项后立即 return ,否则使用 false.

保释

代码

#include <Rcpp.h>

// [[Rcpp::export]]
bool contains(std::vector<std::string> sv, std::string txt) {
    for (auto s: sv) {
        if (s == txt) return true;
    }
    return false;
}

/*** R
sv <- c("a", "b", "c")
contains(sv, "foo")
sv[2] <- "foo"
contains(sv, "foo")
*/

演示

> Rcpp::sourceCpp("~/git/Whosebug/66895973/answer.cpp")

> sv <- c("a", "b", "c")

> contains(sv, "foo")
[1] FALSE

> sv[2] <- "foo"

> contains(sv, "foo")
[1] TRUE
> 

在寻找我们在(大约)10 万行 Rcpp 中可能已经拥有的内容,或者 STL 可能拥有的内容之前,这真的只是草草了事...

这同样适用于您之前的命名属性示例,当然,对于 CharacterVector,and/or 使用从它到 std::vector<std::string> 的转换,我们在这里使用,或者...如果您有较旧的编译器,请将 for 从 C++11 样式切换到 K+R 样式。