2011-11-29 2 views
3

배열 $arr 안에있는 모든 요소를 ​​검사하기 위해 all이라는 함수를 작성하고 boolean 값 (반환 값은 $f 기준)을 반환합니다. 이것은 잘 동작하는 사용자 정의 함수 (코드 $gte0all로 전달 된 참조).PHP는 true() 함수가 있습니까?

그러나 때로는 하나는 배열의 모든 true 값이 포함되어 있는지 확인합니다 : all(true, $arr)trueboolean로 전달 (그리고 true 함수 이름이 아닙니다)입니다 becase 작동하지 않습니다. PHP는 함수처럼 native true()을 가지고 있습니까?

function all($f, array $arr) 
{ 
    return empty($arr) ? false : array_reduce($arr, function($v1, $v2) use ($f) { 
     return $f($v1) && $f($v2); 
    }, true); 
} 

$test = array(1, 6, 2); 
$gte0 = function($v) { return $v >= 0; } 

var_dump(all($gte0, $test)); // True 

$test = array(true, true, false); 
$id = function($v) { return $v; } // <-- this is what i would avoid 
var_dump(all($id, $test)); // False 

all(true, $test); // NOT WORKING because true is passed as boolean 
all('true', $test); // NOT WORKING because true is not a function 

편집 : 또 다른 방법은 all 기능에 $f을 확인 할 수 있습니다 :

$f = is_bool($f) ? ($f ? function($v) { return $v; } 
    : function($v) { return !$v; }): $f; 

trueall 완벽하게 괜찮 호출이를 추가 한 후.

+3

이것은 IMO라는 코드를 작성하는 데 오해의 소지가 있습니다. 특히 코드의 두 번째 부분은 올바른 흐름을 이해하기가 꽤 어렵습니다. – dynamic

+0

@ yes123 주석 끝 부분에 IMHO를 추가해야합니다. – gremo

+1

@Gremo : 의견은 항상 선언적이며 의견을 말하지 않으려 고합니다. 그렇기 때문에 코멘트라고 부릅니다.) – hakre

답변

3

intval 당신이 (배열 만 예에 정수를 포함 특히)을 찾는 일을 할 수 있습니다.

var_dump(all('intval', $test)); // False 

그러나 float을 사용하면 0으로 반올림되므로 원하는 결과가 아닐 수 있습니다.

더 정확한 "기능은"진정한 부울의 반대가 될 것이다 : empty, 그러나 그것은 작동하지, 그래서 당신은 그것을 사용 (반환 값 반전) 할 수 없습니다가

var_dump(!all('empty', $test)); // Does not work! 

을 그리고 PHP에서는 boolval 또는 이와 유사한 함수가 없으므로 필요에 따라 직접 작성하십시오.)

또한 all 함수를 최적화 할 수 있습니다.반복하는 동안 현재 결과가 이미 FALSE 인 경우 최종 결과는 항상 FALSE이됩니다. 그리고 필요 어쨌든 $f()n * 2 번 호출 없습니다 :

function all($f, array $arr) 
{ 
    $result = (bool) $arr; 
    foreach($arr as $v) if (!$f($v)) return FALSE; 
    return $result; 
} 

편집 :

function all($f, array $arr) 
{ 
    return ($c = count($arr)) 
     && ($f ? $arr = array_map($f, $arr) : 1) 
     && $c === count(array_filter($arr)); 
} 

var_dump(all(0, $test)); // False 
:
knittl is right 포인팅 array_filter, 그것은 더 "boolval"기능이 없기 때문에 멋진 것 같다 주어진 어떤 기능을 부울로 변환

첫 번째 함수 매개 변수를 옵션으로 지정하면 array_filter 덕분에 각 배열 요소에 적절한 bool 캐스트가 수행됩니다.

+0

감사합니다. 지금까지 가장 관련성이 높은 답변입니다. 나는 그것을 최적화 할 것이다. – gremo

+0

@Gremo : 나는 그것을 편집하고'array_filter'와 함께 하나의'all' 함수 변형을 추가했습니다, 그것은 knittl에 의해서도 좋은 포인터였습니다. – hakre

+1

+1 초기 루프! 나는 이것이 런타임 및 메모리 (array_filter보다 우수함)와 관련하여 최고의 코드라고 생각한다. 비슷한 점도있었습니다. Btw, 당신은'$ result = (bool) $ a; 할 수 있어야합니다. foreach ($ a와 $ v) {if (! $ f ($ v))가 false를 반환하면; } return $ result;', 모든 결과가 필요없고 – knittl

1

PHP에서는 true() 함수가 없으므로 값을 true와 비교해야합니다.

내가이 일을해야한다고 생각

return ($f === $v1) && ($f === $v2); 

대신

return $f($v1) && $f($v2); 
+0

네,하지만'$ gte0'에서는 작동하지 않습니다. – gremo

+0

첫 문장에 혼란 스럽습니까 - PHP 다음에 마침표가 있어야합니까? –

0

시도 :

function all($f, array $arr) 
{ 
    return empty($arr) ? false : array_reduce($arr, function($v1, $v2) use ($f) { 
     return $f($v1) && $f($v2); 
    }, true); 
} 

function isTrue($a) 
{ 
    return true === $a; 
} 

all("isTrue", $test); 
+0

광산과 동일합니다 :'$ id = function ($ v) {return $ v; }'(신원 함수) ... – gremo

+0

... 또는'function isTrue ($ a) {return (bool) $ a; }', 요구 사항에 따라 다르다. – DaveRandom

+0

@Gremo 필자는'all()'에 전달 된 매개 변수의 인용이 적절하다고 생각한다. ''트루 (True) '는 내 예제의 문자열입니다. 반면에'true'는 당신의 bool입니다. –

2

당신은에서 값 'falsy'가 모두 제거됩니다 PHP의 array_filter 기능을 사용할 수 있습니다 콜백이 지정되지 않은 경우 배열 :

$a = array (true, true, false); 
var_dump($a == array_filter($a)); 
+0

관련 없 음. 코드를 다시 살펴보십시오 ... – gremo

3

값을 최종 값으로 줄일 수있는 부울 값에 매핑하는 것이 더 좋습니다.

function all($map, $data) { 
    if (empty($data)) { return false; } 
    $reduce = function($f, $n) { 
    return $f && $n; 
    }; 
    return array_reduce(array_map($map, $data), $reduce, true); 
} 

$gte0 = function($v) { return $v >= 0; }; 
$gte2 = function($v) { return $v >= 2; }; 

$data = array(1, 2, 3, 4, 5); 
var_dump(all($gte0, $data)); 
var_dump(all($gte2, $data)); 

나서 함수의 결과가 기대 남아 있지만, 필요에 따라 시험을 이룰 수있다. 당신은에 전달 될 한 단계 더 가서지도를 모두 허용하고 기능을 감소시킬 수있다

function mr($map, $reduce, $data) { 
    return array_reduce(array_map($map, $data), $reduce, true); 
}