是否有重用for循环的DRY方法?

时间:2013-03-13 14:35:02

标签: dry

假设我有一个稍微复杂的for循环,用于不同的情况。有没有办法提取forloop并仍然保持代码可读?

例如:

private function bar(){
    for(i=0;i<arrayA.length;i++){
       if(arrayA[i].someVar == foobar){
         doSomethingA();
       }
    }
}
private function foo(){
    for(i=0;i<arrayA.length;i++){
       if(arrayA[i].someVar == foobar){
         doSomethingB();
       }
    }
}

我这样做/回答问题的方法是写下这样的东西:

private function loopFunction(callback:Function){
        for(i=0;i<arrayA.length;i++){
           if(arrayA[i].someVar == foobar){
             callback();
           }
        }
    }
  private function bar(){
       loopFunction(doSomethingA);
  }
  private function foo(){
       loopFunction(doSomethingB);
   }

然而,我发现这种方法有时使代码难以理解,因为你不太清楚谁在做什么。特别是如果传入的函数来自另一个类。有更好的方法吗?

此溶剂可能不起作用的另一个原因是您需要将不同的参数传递给回调函数。例如。

private function bar(){
        for(i=0;i<arrayA.length;i++){
           if(arrayA[i].someVar == foobar){
             doSomethingA(arrayA);
           }
        }
    }
    private function foo(){
        for(i=0;i<arrayA.length;i++){
           if(arrayA[i].someVar == foobar){
             doSomethingB(i);
           }
        }
    }

2 个答案:

答案 0 :(得分:2)

正如其他人所指出的,higher-order functions,例如mapfoldfilter提供了这种功能。当然,具体的实施方式因语言而异。

以下是C#中的示例:

var foobarList = arrayA.Where(x => x.someVar == foobar).ToList();
foobarList.ForEach(x => doSomethingA());
foobarList.ForEach(x => doSomethingB());

和VB.NET:

Dim foobarList = arrayA.Where(Function(x) x.someVar = foobar).ToList()
foobarList.ForEach(Function(x) doSomethingA())
foobarList.ForEach(Function(x) doSomethingB())

和Javascript:

var foobarList = arrayA.filter(function(x) { return x.someVar == foobar });
foobarList.forEach(function(x) { doSomethingA(); });
foobarList.forEach(function(x) { doSomethingB(); });

答案 1 :(得分:1)

当你的代码变得更糟时,你应该停止抽象:)

许多语言都内置了更高级别的构造来处理常见的迭代模式。 C ++ 11具有基于范围的for循环,使迭代数据结构变得不那么繁琐。功能语言通常包含mapfoldfilter