我想这个问题肯定已经被问过好几次了,但我找不到任何东西。
我有一个函数依赖于一个参数(caseset
),该参数可以有两种不同类型。根据其性质,在循环中我需要执行一个操作而不是另一个操作。由于对象的性质在一开始就已知,因此在我看来,每次在循环中都有一个 if
语句是低效且不优雅的。理想情况下,我每次都会应用正确的表达式并在循环顶部选择它。这是一段代码,可以让您了解我想要什么。
SEXP doSomething(SEXP anObject, SEXP caseset, SEXP isMat) {
/*
* here anObject is an external pointer to a C structure,
* caseset is either a character matrix or a data.frame made of character columns.
*/
int i,j,nrow,ncol;
int isMatrix = LOGICAL(isMat)[0];
const char *field;
/*
* Determine the number of rows and columns in each case
*/
if (isMatrix) {
ncol = length(VECTOR_ELT(getAttrib(caseset,R_DimNamesSymbol),1));
nrow = length(caseset)/ncol;
} else {
ncol = length(caseset);
nrow = length(VECTOR_ELT(caseset,0));
}
for (i=0;i<nrow;i++) {
for (j=0;j<ncol;j++) {
if (isMatrix) {
field = CHAR(STRING_ELT(caseset,j*nrow+i));
} else {
field = CHAR(STRING_ELT(VECTOR_ELT(caseset,j),i));
}
/*
* Do stuff involving field and anObject
*/
}
}
return result;
}
我正在编写一个可从 R 调用的 C 函数。我正在传递 R 对象(SEXP
类型)。 caseset
对象可以是矩阵或 data.frame
。我当时正在处理一行,并且由于两个对象存储其元素的方式非常不同,因此要获取表的 (i,j)
值,您必须以不同的方式移动。请注意每次声明的 if
条件(每次调用 doSomething
都会得到相同的结果)。该函数的其余部分相当长。
我当然可以:
- 将
if
条件移到循环之外,并根据isMatrix
的值重写两段相同的代码块(除了一行); - 编写两个几乎相同的函数,并根据
caseset
的性质"dispatch"正确的函数。
但是,上述两个选项对我来说看起来都不优雅。我更希望有一些东西可以让您在循环中应用正确的行,而无需每次检查条件,也不必重写两次代码。
最佳答案
C 并不以优雅而闻名。其他语言可能允许您使用某种迭代器。检查 isMatrix 两次也不错。但当然,您可能需要检查更多次或者支持更多类型。
考虑使用两个基于 isMat 的内部函数:
SEXP doSomething(SEXP anObject, SEXP caseset, SEXP isMat) {
/*
* here anObject is an external pointer to a C structure,
* caseset is either a character matrix or a data.frame made of character columns.
*/
return LOGICAL(isMat)[0] ? doSomethingMatrix(anObject,caseset) : doSomethingFrame(anObject,caseset);
}
static doSomethingMatrix(SEXP anObject, SEXP caseset) {
int i,j,nrow,ncol;
const char *field;
ncol = length(VECTOR_ELT(getAttrib(caseset,R_DimNamesSymbol),1));
nrow = length(caseset)/ncol;
for (i=0;i<nrow;i++) {
for (j=0;j<ncol;j++) {
field = CHAR(STRING_ELT(caseset,j*nrow+i));
// Share the long processing code between the two functions
doStuffField(anObject,field);
}
}
return result;
}
关于c - 根据循环中的条件应用表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33240624/