Pour chaque … pause

Je me sens sale chaque fois que je "bris" hors d'une construction pour-chaque (PHP / Javascript)

Donc, quelque chose comme ça:

// exemple Javascript

for (object in objectList) { if (object.test == true) { //do some process on object break; } } 

Pour les grandes listes d'objets, je voudrais passer par la résolution de problèmes pour une solution plus élégante. Mais pour les petites listes, il n'y a pas de problème de performance notable et donc "pourquoi pas"? C'est rapide et surtout important à comprendre et à suivre.

Mais il "se sent mal". Comme une déclaration goto.

Comment gère-vous ce type de situation?

J'utilise une pause. C'est une solution parfaitement chromulée.

C'est rapide et surtout important à comprendre et à suivre.

Ne vous sentez pas mal au sujet de la rupture. Goto est mal vu parce que c'est rapide et, surtout, pas facile à comprendre et à suivre.

Voyez, la pause ne me dérange pas du tout . La programmation est basée sur goto et for-break – comme toutes les structures de contrôle – est simplement une forme d'utilisation spéciale destinée à améliorer la lisibilité de votre code. Ne vous sentez jamais mal à l'idée d'écrire un code lisible!

Maintenant, je me sens sale au sujet des comparaisons directes avec le true , en particulier lorsque j'utilise l'opérateur de l'équitation de conversion de type … Oh oui. Ce que vous avez écrit – if (object.test == true) – équivaut à écrire if (object.test) , mais nécessite plus de réflexion. Si vous voulez vraiment que cette comparaison ne réussisse que si object.test est à la fois une valeur booléenne et true , vous utiliserez l'opérateur d'égalité stricte ( === ) … Sinon, sautez-le.

Pour les petites listes, il n'y a aucun problème à faire. Comme vous le mentionnez, vous voudrez peut-être réfléchir à une solution plus «élégante» pour les grandes listes (en particulier les listes avec des tailles inconnues).

Parfois, il se sent mal, mais c'est bon. Vous apprendrez à aimer la break dans le temps.

Comme vous l'avez dit "" pourquoi pas? "C'est rapide et surtout important de comprendre et de suivre."

Pourquoi se sentir sale, je vois rien de mal à cela.

Je pense qu'il est plus facile à lire et donc plus facile à entretenir.

C'est comme ça. Break est conçu pour sauter hors d'une boucle. Si vous avez trouvé ce dont vous avez besoin en boucle, pourquoi garder la boucle en marche?

Les interruptions et les continuités ne sont pas prises. Ils sont là pour une raison. Dès que vous avez fini avec une structure de boucle, sortez de la boucle .

Maintenant, ce que j'éviterais, c'est l'imbrication très, très profonde (aka la tête de flèche anti-motif).

 if (someCondition) { for (thing in collection) { if (someOtherCondition) { break; } } } 

Si vous allez faire une pause, assurez-vous que vous avez structuré votre code afin qu'il ne soit jamais un niveau de niveau. Utilisez les appels de fonction pour garder l'itération aussi peu profonde que possible.

 if (someCondition) { loopThroughCollection(collection); } function loopThroughCollection(collection) { for (thing in collection) { if (someOtherCondition) { doSomethingToObject(thing); break; } } } function doSomethingToObject(thing) { // etc. } 

Je ne vois vraiment pas un problème avec la sortie d'une boucle for. Sauf si vous avez une sorte de table de hash, un dictionnaire où vous avez une sorte de clé pour obtenir une valeur, il n'y a pas d'autre moyen.

J'utiliserais un énoncé de récurrence.

En général, il n'y a pas de problème avec la déclaration de break . Cependant, votre code peut devenir un problème si des blocs comme ceux-ci apparaissent dans différents endroits de votre base de code. Dans ce cas, les relevés de break sont codables pour le code dupliqué.

Vous pouvez facilement extraire la recherche dans une fonction réutilisable:

 function findFirst(objectList, test) { for (var key in objectList) { var value = objectList[key]; if (test(value)) return value; } return null; } var first = findFirst(objectList, function(object) { return object.test == true; } if (first) { //do some process on object } 

Si vous traitez toujours l'élément trouvé d'une certaine manière, vous pouvez simplifier votre code:

 function processFirstMatch(objectList, test, processor) { var first = findFirst(objectList, test); if (first) processor(first); } processFirst( objectList, function(object) { return object.test == true; }, function(object) { //do some process on object } } 

Ainsi, vous pouvez utiliser la fonctionnalité de JavaScript fonctionnelle pour rendre votre code original beaucoup plus expressif. Comme effet secondaire, cela poussera la déclaration de rupture de votre base de code habituelle dans une fonction d'aide.

Peut-être que je suis mal compris dans votre cas d'utilisation, mais pourquoi se briser? Je suppose que vous attendez que le test soit vrai pour au plus un élément de la liste?

S'il n'y a pas de problème de performance et que vous souhaitez nettoyer le code, vous pouvez toujours ignorer le test et la pause.

 for (object in objectList) { //do some process on object } 

De cette façon, si vous avez besoin de faire le processus sur plus d'un élément, votre code ne sera pas interrompu (jeu de mots).

Utiliser un

 Object object; int index = 0; do { object = objectList[index]; index++; } while (object.test == false) 

Si la rupture d'une boucle for vous rend mal à l'aise.

Ma préférence est d'utiliser simplement une break . C'est rapide et ne complique généralement pas les choses.

Si vous utilisez une boucle for , while ou do while while, vous pouvez utiliser une variable pour déterminer si vous souhaitez ou non continuer:

 for ($i = 0, $c = true; ($i < 10) && $c; $i++) { // do stuff if ($condition) { $c= false; } } 

La seule façon de se foreach une boucle foreach est de se break ou de return .