对于像 NA
这样的特殊值或 NaN
, boost::unordered_map
每次我使用 insert
时都会创建一个新 key .
// [[Rcpp::depends(BH)]]
#include <boost/unordered_map.hpp>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test_unordered_map(NumericVector vec) {
boost::unordered_map<double, int> mymap;
int n = vec.size();
for (int i = 0; i < n; i++) {
mymap.insert(std::make_pair(vec[i], i));
}
boost::unordered_map<double, int>::iterator it = mymap.begin(), end = mymap.end();
while (it != end) {
Rcout << it->first << "\t";
it++;
}
Rcout << std::endl;
}
/*** R
x <- c(sample(10, 100, TRUE), rep(NA, 5), NaN) + 0
test_unordered_map(x)
*/
结果:
> x <- c(sample(10, 100, TRUE), rep(NA, 5), NaN)
> test_unordered_map(x)
nan nan nan nan nan nan 4 10 9 5 7 6 2 3 1 8
如何只为 NA
创建一个 key 和一个 NaN
?
最佳答案
bartop's idea使用自定义比较器很好,尽管特定形式对我不起作用。所以我用了 Boost's documentation作为起点。结合合适functions from R我得到:
// [[Rcpp::depends(BH)]]
#include <boost/unordered_map.hpp>
#include <Rcpp.h>
using namespace Rcpp;
struct R_equal_to : std::binary_function<double, double, bool> {
bool operator()(double x, double y) const {
return (R_IsNA(x) && R_IsNA(y)) ||
(R_IsNaN(x) && R_IsNaN(y)) ||
(x == y);
}
};
// [[Rcpp::export]]
void test_unordered_map(NumericVector vec) {
boost::unordered_map<double, int, boost::hash<double>, R_equal_to> mymap;
int n = vec.size();
for (int i = 0; i < n; i++) {
mymap.insert(std::make_pair(vec[i], i));
}
boost::unordered_map<double, int>::iterator it = mymap.begin(), end = mymap.end();
while (it != end) {
Rcout << it->first << "\t";
it++;
}
Rcout << std::endl;
}
/*** R
x <- c(sample(10, 100, TRUE), rep(NA, 5), NaN) + 0
test_unordered_map(x)
*/
结果:
> x <- c(sample(10, 100, TRUE), rep(NA, 5), NaN) + 0
> test_unordered_map(x)
7 2 nan nan 4 6 9 5 10 8 1 3
根据需要,NA
和NaN
只插入一次。但是,无法在此输出中区分它们,因为 R 的 NA
只是一个 special form of an IEEE NaN。 .
关于c++ - 特殊值不能用作 unordered_map 中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51986106/