2009-12-11 13 views
11

me siento sucia cada vez que "ruptura" de un (PHP/Javascript) para cada constructo-para cada ... romper

Así que algo como esto:

// Javascript ejemplo

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

} 

Para objectLists grandes Me gustaría pasar por la construcción de problemas una solución más elegante. Pero para las listas pequeñas no hay un problema de rendimiento notable y, por lo tanto, "¿por qué no?" Es rápido y, lo que es más importante, fácil de entender y seguir.

Pero simplemente "se siente mal". Algo así como una declaración goto.

¿Cómo manejas este tipo de situación?

+0

Sé lo que dices, pero todo el mundo está en el camino correcto: está bien, especialmente para listas pequeñas. Mis listas grandes suelen ser de consultas DB, y si tengo que usar la función LIMIT solo para extraer un subconjunto de registros. Respuesta corta: no se sienta mal por usar "break" o "continue" – jbnunn

+0

Su código no funcionará de esta manera porque el operador for..in siempre repetirá las teclas del objeto (strings). Probablemente se refiera a algo como esto: for (clave var en objectList) { var object = objectList [key]; ... } –

Respuesta

27

Uso un descanso. Es una solución perfectamente cromática.

+16

+1 para el uso de la palabra "cromulent". –

+0

'cromulent'! me gusta –

+0

Lo que me gusta de "cromulent" es que significa lo que es, una palabra que es perfectamente obvia de lo que significa el contexto. –

1

Realmente no veo nada malo con salir de un bucle for. A menos que tenga algún tipo de tabla hash, diccionario donde tenga algún tipo de clave para obtener un valor, realmente no hay otra manera.

1

Usaría una declaración break.

2

Para listas pequeñas, no hay ningún problema al hacer esto. Como mencionas, es posible que quieras pensar en una solución más "elegante" para listas grandes (especialmente listas con tamaños desconocidos).

A veces se siente mal, pero está bien. Aprenderás a amar break a tiempo.

+0

No lo sé .... He estado programando durante unos 15 años. Lo hago (uso el receso), parece que a veces es una trampa ... – ChronoFish

2

Como dijo "¿por qué no?" Es rápido y, lo que es más importante, fácil de entender y seguir ".

Por qué sentirse sucio, no veo nada de malo en esto.

2

Creo que es más fácil de leer y, por lo tanto, más fácil de mantener.

2

Está destinado a ser así. Break está diseñado para saltar fuera de un bucle. Si ha encontrado lo que necesita en un bucle, ¿por qué sigue funcionando?

0

Tal vez estoy malinterpretando su caso de uso, pero ¿por qué romper en absoluto? Supongo que espera que la prueba sea cierta para, como máximo, un elemento de la lista.

Si no hay problemas de rendimiento y desea limpiar el código, siempre se puede saltear la prueba y el descanso.

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

De esta forma si usted tiene que hacer el proceso en más de un elemento de su código no se romperá (nunca mejor dicho).

+0

Solo rompo los casos donde quiero encontrar el primer (o único) ítem que coincida con mi cláusula de prueba. Simplemente dejar que el ciclo continúe es solo ciclos de encendido en estos casos. – ChronoFish

+0

Depende de si le preocupa más la quema de ciclos cerebrales o ciclos de CPU. Breaking es una optimización, puede ser justificada, pero si la lista es pequeña, considere dejarla hasta que sepa que la necesita. – ctford

0

Mi preferencia es simplemente usar un break. Es rápido y, por lo general, no complica las cosas.

Si utiliza un bucle for, while o do while, puede utilizar una variable para determinar si debe o no continuar:

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

    if ($condition) { 
     $c= false; 
    } 
} 

La única manera de romper un bucle foreach es break o return .

+0

Lo hago, aunque generalmente solo con un ciclo 'while'. – Tenner

+4

¿Prefiere agregar una bandera, cinco líneas y '&&' que 'romper;'? – Tordek

+0

-1 esto no es un beneficio – JonH

5

Es rápido y, lo que es más importante, fácil de entender y seguir.

No te sientas mal por el descanso. Goto está mal visto porque es rápido y más importante no fácil de entender y seguir.

2

Las interrupciones y continúan no son buenas. Ellos están ahí por una razón. Tan pronto como haya terminado con una estructura de bucle, salga del ciclo.

Ahora, lo que yo evitaría es una anidación muy, muy profunda (por ejemplo, el diseño anti-patrón de punta de flecha).

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

Si se va a hacer una pausa, a continuación, asegúrese de que usted tiene la estructura de su código para que sea sólo alguna vez un nivel de profundidad. Use llamadas a funciones para mantener la iteración lo más superficial posible.

if (someCondition) 
{ 
    loopThroughCollection(collection); 
} 

function loopThroughCollection(collection) 
{ 
    for (thing in collection) 
    { 
     if (someOtherCondition) 
     { 
      doSomethingToObject(thing); 
      break; 
     } 
    } 
} 

function doSomethingToObject(thing) 
{ 
    // etc. 
} 
+0

Érase una vez, cuando empecé a programar, tenía unas sentencias if geniales muy interesantes para la verificación de contraseñas .... :) – starcorn

0

Utilice un

Object object; 
int index = 0; 

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

si romper un bucle de for hace sentir incómoda.

+0

Eso supone un índice numérico. – ChronoFish

+0

Amplíe la idea a cualquier tipo de índice, siempre y cuando se pueda enumerar y haya una manera de ir de un elemento al siguiente. – luvieere

4

Ver, el descanso no me molesta en absoluto. La programación es construida en goto, y for-break - como todas las estructuras de control - es simplemente una forma especial de goto destinada a mejorar la legibilidad de su código. ¡Nunca te sientas mal por escribir un código legible!

Ahora, yo hago sienten sucias sobre las comparaciones directas a true, especialmente cuando se utiliza el operador de igualdad tipo de conversión ... Oh, sí. Lo que has escrito - if (object.test == true) - es equivalente a escribir if (object.test), pero requiere más reflexión. Si realmente quiere que la comparación solo tenga éxito si object.test es un valor booleano ytrue, entonces usaría the strict equality operator (===) ... De lo contrario, sáltelo.

+2

Buen punto sobre la cosa "== verdadero". Siempre quiero sugerir que las personas usen "if ((object.test == true) == true)", solo para ver si obtienen lo ridículo que es. –

1

En general, no hay nada de malo en la instrucción break. Sin embargo, su código puede convertirse en un problema si bloques como estos aparecen en diferentes lugares de su base de código. En este caso, las sentencias break son un código pequeño para el código duplicado.

Puede extraer fácilmente la búsqueda en una función reutilizable:

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 siempre procesar el elemento que se encuentra de alguna manera se puede simplificar el código más:

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 
    } 
} 

para que pueda usar el poder de las características funcionales en JavaScript para hacer que su código original sea mucho más expresivo. Como efecto colateral, esto desplazará la declaración break de su base de código normal a una función de ayuda.