2013-07-25 19 views
15

Gibt es eine Möglichkeit, eine array_walk aus der anonymen Funktion zu stoppen?Break array_walk von anonymer Funktion

Hier ist ein Beispielcode (der funktioniert) zu zeigen, was ich meine, die überprüft, ob ein Array nur numerische Werte hat.

$valid = true; 
array_walk($parent, function ($value) use (&$valid) { 
    if (!is_numeric($value)) { 
     $valid = false; 
    } 
}); 

return $valid ? 'Valid' : 'Invalid'; 

Wenn ich groß genug Array haben, und der erste Eintrag ungültig ist, der Rest der (redundant) Kontrollen noch zu tun, so würde Ich mag die Hinrichtung stoppen.

Die Verwendung von break/continue funktioniert nicht (Fehler: Fatal error: Cannot break/continue 1 level in ...).

Hinweis: Ich habe nicht den Code neu schreiben will, ich will nur wissen, IF dies möglich ist.

+3

Sie * konnte * werfen, dann fangen, eine Ausnahme. Natürlich ist es falsch, aber es ist möglich. –

+0

Nicht direkt möglich, aber wo genau zeichnen Sie die Linie für das Umschreiben des Codes? (Die 'Exception'-Lösung hört sich an, als würde sie funktionieren, aber ich würde eher eine einfache 'foreach' als das tun). – Jon

+0

@Jon: Nun, ich war neugierig, ob es für solche Funktionen möglich war. Ich möchte nicht 'for' /' foreach' verwenden, das ist es (meistens eine theoretische Frage :)). Anthony, du solltest das als Antwort posten. –

Antwort

11

Wie gesagt, theoretisch ist es möglich, aber ich würde davon abraten. So verwenden Sie eine Ausnahme, um die zu umgehen.

<?php 
$isValid = false; 

$array = range(1, 5); 

try { 
    array_walk($array, function($value) { 
     $isAMagicNumber = 3 === $value; 
     if ($isAMagicNumber) { 
      throw new Exception; 
     } 
    }); 
}catch(Exception $exception) { 
    $isValid = true; 
} 

var_dump($isValid); 

/* 
    bool(true) 
*/ 
+0

Dies kann nützlich sein, wenn dies eine Kernüberprüfung in Ihrer Anwendung ist und Sie trotzdem eine Ausnahme auslösen würden. B. "neue InvalidInputException;" werfen und dann ordnungsgemäß behandeln. Aber in den meisten Fällen ist es besser, dies nicht zu tun :) Danke für die Antwort! –

6

Sie können eine statische Flagge innerhalb der anonymen Funktion gesetzt:

array_walk($ary, function($item) { 
    static $done = false; 
    if($done) { 
     return; 
    } 

    // … your code 

    if($myBreakCondition) { 
     $done = true; 
     return; 
    } 
}); 

Dadurch wird die Iteration nicht wirklich zu stoppen, aber alle weiteren Zyklen, nachdem die Flagge einfach nichts tun gesetzt ist. Nicht sehr effizient, aber es könnte ohne größere Auswirkungen auf die Leistung funktionieren, wenn die iterierten Arrays nicht zu groß sind.

$valid = true; 
array_walk($parent, function($value) use(&$valid) { 
    static $done = false; 
    if($done) { 
     return; 
    } 

    if(!is_numeric($value)) { 
     $valid = false; 
     $done = true; 
     return; 
    } 
}); 
return $valid ? 'Valid' : 'Invalid'; 

Aber es wird eigentlich nicht viel Unterschied, wenn es überhaupt kein „Bruch“ ist:

In Ihrem Fall würde der Code sein. Für jeden ungültigen Wert würde nur der Wert "false" vergeben, was nicht wichtig ist, da das Ergebnis immer noch falsch wäre. Vielleicht wäre es noch effizienter, dass meine statische Variable schummelt.

in Ihrem Fall persönlich würde ich array_filter statt:

$valid = count(array_filter($parent, 'is_numeric')) == count($parent); 

oder nur

$valid = array_filter($parent, 'is_numeric')) == $parent; 

Wenn alle Werte in dem $parent Array numerisch sind, würden sie alle Anwesenden nach der Filterung sein. Andererseits würde jeder nicht-numerische Wert im Array den Inhalt des gefilterten Arrays (Verringerung der Elementanzahl) beeinflussen, und der Vergleich würde den Wert false ergeben.

Verwandte Themen