2009-10-31 6 views
7

나는 다음과 같은 코드를 작성한다.이것은 나쁜 패턴입니까? (for/foreach 루프 내부 스위치)

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]); 
} 

(또는 그와 비슷한 것)

필요한 경우 정확한 코드를 게시 할 수 있습니다. 그러나 이것은 어떻게되는지에 대한 일반적인 개요입니다. 비판을 멀리하십시오, 그러나 나가 도움을 여기 찾고 있다는 것을 기억하십시오. 그래서 내가 심각하게 잘못된 것을하고 있다면, 그것을 지적하십시오.

+0

이 코드에서 볼 수있는 중요한 점은 $ 배열에 값이 거의 없다면 성능이 좋지만 많은 수의 값이있는 경우 속도가 훨씬 느릴 것이라고 예상합니다 (단지 10,000 개의 값을 생각하면됩니다). 해당 스위치는 배열의 모든 값에 대해 실행되어야합니다. 작업중인 데이터를 알고 있으므로 이에 따라 솔루션을 선택하십시오. 개인적으로는 if의 경우를 수행하지만 그게 나일뿐입니다. – Tom

답변

15

사전/연관 배열의 키에 함수를 매핑하는 것은이 상황에 대한 일반적인 접근 방법입니다 (@jldupont가 언급했듯이) - PHP뿐만 아니라 연관 배열을 사용하는 많은 동적 언어에서도 사용할 수 있습니다. 예를 들어, 파이썬과 루아는 심지어 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. 

그것은 당신이 두 개의 서로 다른 값을 가질 때 과잉이지만, 분명히 그것은 당신이이 상황의 수보다 가치있는 방법이된다 표지가 증가합니다.

+0

이것은 생각하지 못했던 해결책입니다. 게시했을 때 염두에 두었던 코드와 관련하여 이것은 과도 함이지만 분명히 생각할 수 있습니다. 감사합니다! –

+0

이것은 실제로 데이터 중심의 디스패치 테이블로, 수십 년간 엄청나게 자주 사용되는 동안 가장 유용한 기술임을 입증했습니다. –

+0

또한이 접근법이 유용하려면 언어가 동적 일 필요는 없습니다. C++, C# 및 vb.net에서도 유사한 작업을 수행했습니다. :) –

4

저는 foreach 루프에서 스위치를 사용하는 경향이 있습니다. 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; 
    } 
} 
0

이 시도 :

실행을 각 버전을 통해 - 스위치로하고, 경우에 - 백만 배. 각각의 시간을 실행합니다.

어느 것이 더 빨리 실행되는지 알려주십시오.

+1

찾고 있지 않습니다. 최적화 기술을 위해 설계 기법이 더 나은 경우 (존재한다면) –

1

다른 가능성이 있습니다. 함수에 작업을 전달하기 위해 사전 조회를 사용합니다.

$ key를 "key"로 사용하여 함수를 조회하고 함수 참조를 검색하여 $ value를 매개 변수로 적용합니다.

나를 용서하되 PHP-fu는 녹슬니다.

0

아무 문제가 없습니다.

2 ~ 3 개 항목 만있는 경우 코드 복잡성을 위해 if를 사용합니다. 만약 당신이 5 이상을 가지고 있다면 나는 스위치를 가지고 갈 것입니다 ...

5

"나쁜"해결책은 아니지만 언제나처럼 대안이 있습니다. 예를 들어 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); 
} 

입력 문자열을 삭제하고 처리기에 메서드가 있는지 확인하려면 코드가 필요할 수 있지만 몇 가지 아이디어가있을 수 있습니다.

+0

분명히 나에게 몇 가지 아이디어, 당신의 답변을 주셔서 감사합니다 jheddings. +1 –