Ответ 1
Я использую перерыв. Это идеальное решение.
Я чувствую себя грязным каждый раз, когда я "ломаюсь" из каждой конструкции (PHP/Javascript)
Так что-то вроде этого:
//Пример Javascript
for (object in objectList)
{
if (object.test == true)
{
//do some process on object
break;
}
}
Для больших объектных списков я бы смог выстроить более элегантное решение. Но для небольших списков нет заметной проблемы с производительностью, и поэтому "почему бы и нет"? Это быстро и, что более важно, легко понять и следовать.
Но он просто "чувствует себя не так". Вид вроде утверждения goto.
Как вы справляетесь с такой ситуацией?
Я использую перерыв. Это идеальное решение.
Это быстро и, что важнее, легко понять и следовать.
Не чувствуй себя плохо в перерыве. Goto неодобрительно, потому что это быстро и важнее не просто понять и следовать.
Видишь, перерыв меня совсем не пугает. Программирование построено на goto, а for-break - как и все структуры управления - это просто специальная форма goto, предназначенная для улучшения читаемости вашего кода. Никогда не плохо себя чувствуешь в написании читаемого кода!
Теперь я do чувствую себя грязным относительно прямых сравнений с true
, особенно при использовании оператора равенства преобразования типов... О да. То, что вы написали - if (object.test == true)
- эквивалентно написанию if (object.test)
, но требует больше мысли. Если вы действительно хотите, чтобы сравнение было успешным только в том случае, если object.test
является как логическим значением, так и true
, вы должны использовать оператор строгого равенства (===
)... В противном случае пропустите его.
Для небольших списков нет никаких проблем с этим. Как вы упомянули, вы можете подумать о более "элегантном" решении для больших списков (особенно списки с неизвестными размерами).
Иногда это кажется неправильным, но все в порядке. Вы научитесь любить break
вовремя.
Как вы сказали "почему бы и нет?" Это быстро и, что еще важнее, легко понять и следовать ".
Зачем чувствовать себя грязным, я не вижу в этом ничего плохого.
Я думаю, что читать легче и, следовательно, легче поддерживать.
Он должен быть таким. Break предназначен для выпрыгивания из цикла. Если вы нашли то, что вам нужно в цикле, почему нужно продолжать цикл?
Разрывы и продолжения не являются доступными. Они там не просто так. Как только вы закончите с структурой цикла, выйдите из цикла.
Теперь, что бы я избежал, очень, очень глубокое гнездование (a.k.a. дизайн антистатика стрелки).
if (someCondition)
{
for (thing in collection)
{
if (someOtherCondition)
{
break;
}
}
}
Если вы собираетесь сделать перерыв, убедитесь, что вы структурируете свой код, чтобы он был только на одном уровне. Используйте вызовы функций, чтобы сохранить итерацию как можно более мелкой.
if (someCondition)
{
loopThroughCollection(collection);
}
function loopThroughCollection(collection)
{
for (thing in collection)
{
if (someOtherCondition)
{
doSomethingToObject(thing);
break;
}
}
}
function doSomethingToObject(thing)
{
// etc.
}
Я действительно не вижу ничего неправильного в выходе из цикла for. Если у вас нет какой-либо хеш-таблицы, словарь, в котором у вас есть какой-то ключ для получения значения, на самом деле нет другого пути.
Я бы использовал оператор break
.
В общем, нет ничего плохого в инструкции break
. Однако ваш код может стать проблемой, если такие блоки появятся в разных местах вашей базы кода. В этом случае операторы break
представляют собой код, маленький для дублированного кода.
Вы можете легко извлечь поиск в функцию многократного использования:
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
}
Если вы всегда обрабатываете найденный элемент каким-либо образом, вы также можете упростить свой код:
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
}
}
Таким образом, вы можете использовать возможности функциональных возможностей JavaScript, чтобы сделать ваш оригинальный код более выразительным. В качестве побочного эффекта это приведет к выведению выражения break
из вашей обычной базы кода в вспомогательную функцию.
Возможно, я неправильно понимаю ваш случай использования, но зачем вообще ломаться? Я предполагаю, что вы ожидаете, что тест будет истинным для не более одного элемента в списке?
Если нет проблемы с производительностью и вы хотите очистить код, вы всегда можете пропустить тест и перерыв.
for (object in objectList)
{
//do some process on object
}
Таким образом, если вам нужно выполнить этот процесс более чем на одном элементе, ваш код не сломается (каламбур).
Мое предпочтение - просто использовать break
. Это быстро и обычно не усложняет ситуацию.
Если вы используете цикл for
, while
или do while
, вы можете использовать переменную, чтобы определить, продолжать или нет:
for ($i = 0, $c = true; ($i < 10) && $c; $i++) {
// do stuff
if ($condition) {
$c= false;
}
}
Единственный способ выйти из цикла foreach
- break
или return
.
Используйте
Object object;
int index = 0;
do
{
object = objectList[index];
index++;
}
while (object.test == false)
если нарушение от цикла for
заставляет вас чувствовать себя неловко.