c - 根据循环中的条件应用表达式

标签 c r

我想这个问题肯定已经被问过好几次了,但我找不到任何东西。

我有一个函数依赖于一个参数(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/

相关文章:

c - 从c程序在linux中设置时间

r - 在 R 中使用 dplyr/magrittr 删除/删除列

r - 使用 Scala 中的 R 并从 R 中调用 Scala?

列表中的 R 语言函数

r - 如何使用 dplyr 中的累积函数在 R 中按行重现数据帧或 tibble?

r - 使用 R 进行布朗运动模拟

c - 找不到gmp库

c++ - 带字符串的邮槽

c++ - 为什么这样的 OpenAL 代码会在 Visual Studio 2008 中出现这样的错误?

c - 注释中的 "@(#)<filename>"是什么意思?