代码之家  ›  专栏  ›  技术社区  ›  ftdysa

这是个坏模式吗?(在内部切换/foreach循环)

  •  7
  • ftdysa  · 技术社区  · 15 年前

    我发现自己在写代码,比如:

    foreach($array as $key => $value) {
        switch($key) {
            case 'something':
                doSomething($value);
                break;
            case 'somethingelse':
                doSomethingElse($value);
                break;
        }
    }
    

    有更好的方法吗?在我看来很脏,但我可能只是想过头了。

    我唯一能想到的另一种选择是为每个键编写一个if语句,这似乎没有什么好的。即:

    if($array[0] == 'something') {
        doSomething($array[0]);
    }
    if($array[1] == 'somethingelse') {
        doSomethingElse($array[1]);
    }
    

    (或类似的东西)

    如果需要的话,我可以发布精确的代码,但这是所发生的事情的大致轮廓。请批评一下,但请记住,我在这里寻求帮助。所以如果我做了一件非常错误的事情,那就指出它。

    6 回复  |  直到 12 年前
        1
  •  15
  •   Emil Vikström    12 年前

    在这种情况下,将函数映射到字典/关联数组中的键是一种常见的方法(正如@jldupont所提到的),不仅在PHP中,而且在许多具有关联数组的动态语言中。例如,python和lua甚至没有 switch语句——这几乎是模拟交换机的唯一方法。

    考虑这种方法:

    <?
    $arr[] = "bye";
    $arr[] = "hi";
    
    function sayHi() { print("Hello.\n"); }
    function sayBye() { print("Goodbye.\n"); }
    
    $funcs["hi"] = sayHi;
    $funcs["bye"] = sayBye;
    
    foreach($arr as $k){
        $funcs[$k]();
    }
    
    ?>
    

    输出:

    Goodbye.
    Hello.
    

    当您只有两个不同的值时,这是一种过度杀伤力,但是很明显,随着您必须处理的情况数量的增加,这会成为一种更有价值的方法。

        2
  •  5
  •   jheddings    15 年前

    这不是一个“坏”的解决方案,但和往常一样,还有其他选择。例如,可以去掉switch语句,并对字符串使用解释处理程序。这类似于函数指针的列表,但是您不必保持列表的最新状态来添加新的行为;只需将新函数添加到处理程序就可以了。

    $array = array(
      "something" => "itsasecret",
      "somethingelse" => "i can't tell you",
    );
    
    class Handler {
      static function something($value) {
        printf("something: %s\n", $value);
      }
    
      static function somethingelse($value) {
        printf("somethingelse: %s\n", $value);
      }
    }
    
    $handler = new Handler();
    foreach($array as $key => $value) {
      $handler->$key($value);
    }
    

    您可能需要一些代码来清理输入字符串并确保该方法存在于处理程序中,但这可能会给您一些建议。

        3
  •  4
  •   Nettogrof    15 年前

    我倾向于在前臂回路中使用开关。imho比一堆if还脏。

    您可以将开关置于其他功能中,例如:

    foreach($array as $key => $value) {
       doTransaction($key , $value);
    }
    
    ...
    
    function doTransaction($key, $value){
         switch($key) {
            case 'something':
                doSomething($value);
                break;
            case 'somethingelse':
                doSomethingElse($value);
               break;
        }
    }
    
        4
  •  1
  •   jldupont    15 年前

    还有(至少)另一种可能性:使用字典查找将工作分派给函数。

    使用$key作为“key”查找函数,检索函数引用并以$value作为参数应用它。

    原谅我,我的php-fu有点生锈了。

        5
  •  0
  •   inked    15 年前

    试试这个:

    用开关和中频运行每个版本一百万次。每次运行的时间。

    让我们知道哪个跑得更快。

        6
  •  0
  •   DOOManiac    15 年前

    没什么问题。

    如果您只有2或3个项目,那么为了代码的复杂性,我将使用if。如果你有5个以上,我绝对会带着开关走…