processnextblockofitems

processnextblockofitems

在我的命令式scala代码中,我有一个算法:

def myProcessor(val items: List) {
  var numProcessed = 0
  while(numProcessed < items.size) {
    val processedSoFar = items.size - numProcessed
    numProcessed += processNextBlockOfItems(items, processedSoFar)
  }
}

我希望保留“块处理”功能,而不仅仅是在项目列表上执行“takewhile”。我怎样才能用函数式重写呢?

最佳答案

所以,这取决于你认为什么更实用,但这里有一个版本没有'var'

  def myProcessorFunctional(items: List[Int]) {
    def myProcessorHelper(items: List[Int], numProcessed: Int) {
      if (numProcessed < items.size) {
        val processedSoFar = items.size - numProcessed
        myProcessorHelper(items,
            numProcessed + processNextBlockOfItems(items, processedSoFar))
      }
    }
    myProcessorHelper(items, 0)
  }

(使它成为一个int列表只是为了简单起见,使用一个通用列表会很容易)
我不得不说,这是我不介意可变变量的情况之一——很明显,没有任何对它的引用能逃过方法。
但正如我在上面的评论中所说的,processnextblockofitems本质上是非功能性的,因为它需要它的副作用。一种更实用的方法是它返回到目前为止的处理状态,然后在随后的调用中更新(并返回)这个状态。现在,如果您正在处理两个不同的项列表,您将面临在processnextblockofitems中维护两个不同的部分处理状态的问题…
稍后:
仍然忽略状态问题,一个方便的更改是,如果processnextblockofitems总是处理传递给它的项列表的第一个块,返回它尚未处理的其余项(如果使用list,这是方便和有效的,所以我想知道为什么要使用indicies)。
这会产生如下结果:
  def myProcessorMoreFunctional(items: List[Int]) {
    if (!items.isEmpty) {
        myProcessorMoreFunctional(processNextBlockOfItems(items))
      }
  }

10-01 17:51