简体   繁体   English

每个...休息

[英]for each … break

I feel dirty every time I "break" out of a for-each construct (PHP/Javascript) 每次我从for-each构造中“断开”时我都觉得很脏(PHP / Javascript)

So something like this: 所以像这样:

// Javascript example // Javascript示例

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

}

For large objectLists I would go through the hassle building a more elegant solution. 对于大型对象列表,我将通过麻烦构建更优雅的解决方案。 But for small lists there is no noticeable performance issue and hence "why not?" 但对于小型列表,没有明显的性能问题,因此“为什么不呢?” It's quick and more importantly easy to understand and follow. 它很快,更重要的是易于理解和遵循。

But it just "feels wrong". 但它只是“感觉不对”。 Kind of like a goto statement. 有点像goto声明。

How do you handle this kind of situation? 你是如何处理这种情况的?

I use a break. 我休息一下。 It's a perfectly cromulent solution. 这是一个完美的解决方案。

It's quick and more importantly easy to understand and follow. 它很快,更重要的是易于理解和遵循。

Don't feel bad about break. 不要为休息感到难过。 Goto is frowned upon because it's quick and more importantly not easy to understand and follow. Goto不赞成因为它很快,更重要的是容易理解和遵循。

See, the break doesn't bug me at all . 看,休息不会让我烦恼 Programming is built on goto, and for-break - like all control structures - is merely a special-purpose form of goto meant to improve the readability of your code. 编程建立在goto之上,而for-break就像所有控制结构一样 - 仅仅是一种特殊用途的goto形式,旨在提高代码的可读性。 Don't ever feel bad about writing readable code! 编写可读代码永远不会感到难过!

Now, I do feel dirty about direct comparisons to true , especially when using the type-converting equality operator... Oh yeah. 现在,我确实觉得直接比较为true特别是当使用类型转换相等运算符时...哦是的。 What you've written - if (object.test == true) - is equivalent to writing if (object.test) , but requires more thought. 你写的是什么 - if (object.test == true) - 相当于写if (object.test) ,但需要更多思考。 If you really want that comparison to only succeed if object.test is both a boolean value and true , then you'd use the strict equality operator ( === ) ... Otherwise, skip it. 如果你真的希望只有当object.test既是boolean值又是 true才能成功,那么你就可以使用严格相等运算符( === ...否则,跳过它。

For small lists, there's no issue with doing this. 对于小型列表,这样做没有问题。 As you mention, you may want to think about a more 'elegant' solution for large lists (especially lists with unknown sizes). 正如您所提到的,您可能想要为大型列表(尤其是大小未知的列表)考虑更“优雅”的解决方案。

Sometimes it feels wrong, but it's all right. 有时感觉不对,但没关系。 You'll learn to love break in time. 你会学会爱和时间break

Like you said ""why not?" It's quick and more importantly easy to understand and follow." 就像你说“”为什么不呢?“它很快,更重要的是易于理解和遵循。”

Why feel dirty, I see nothing wrong with this. 为什么感觉很脏,我觉得这没什么不对。

我认为更容易阅读,因此更容易维护。

It is meant to be like it. 它应该是这样的。 Break is designed to jump out of a loop. Break旨在跳出循环。 If you have found what you need in a loop why keep the loop going? 如果你在循环中找到了你需要的东西,为什么要保持循环?

Breaks and continues are not gotos. 休息和继续都没有。 They are there for a reason. 他们是有原因的。 As soon as you're done with a loop structure, get out of the loop . 一旦完成循环结构, 就离开循环

Now, what I would avoid is very, very deep nesting (aka the arrowhead design anti-pattern). 现在,我要避免的是非常非常深的嵌套(也就是箭头设计反模式)。

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

If you are going to do a break, then make sure that you've structure your code so that it's only ever one level deep. 如果您要休息一下,那么请确保您已经构建了代码,以便它只有一个级别。 Use function calls to keep the iteration as shallow as possible. 使用函数调用使迭代尽可能浅。

if (someCondition)
{
    loopThroughCollection(collection);
}

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

function doSomethingToObject(thing)
{
    // etc.
}

I really don't see anythign wrong with breaking out of a for loop. 我真的没有看到打破for循环的任何错误。 Unless you have some sort of hash table, dictionary where you have some sort of key to obtain a value there really is no other way. 除非你有某种哈希表,你可以通过某种键来获取值,但实际上没有别的办法。

我会使用break声明。

In general there is nothing wrong with the break statement. 一般来说, break语句没有任何问题。 However your code can become a problem if blocks like these appear in different places of your code base. 但是,如果像这样的块出现在代码库的不同位置,则代码可能会成为问题。 In this case the break statements are code small for duplicated code. 在这种情况下, break语句对于重复代码来说代码很小。

You can easily extract the search into a reusable function: 您可以轻松地将搜索提取到可重用的函数中:

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
}

If you always process the found element in some way you can simplify your code further: 如果您始终以某种方式处理找到的元素,则可以进一步简化代码:

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

So you can use the power of the functional features in JavaScript to make your original code much more expressive. 因此,您可以使用JavaScript中的功能强大功能,使您的原始代码更具表现力。 As a side effect this will push the break statement out of your regular code base into a helper function. 作为副作用,这会将break语句从常规代码库中推送到辅助函数中。

Perhaps I'm misunderstanding your use-case, but why break at all? 也许我误解了你的用例,但为什么要打破呢? I'm assuming you're expecting the test to be true for at most one element in the list? 我假设你期望测试对于列表中的至多一个元素是真的吗?

If there's no performance issue and you want to clean up the code you could always skip the test and the break. 如果没有性能问题并且您想要清理代码,则可以始终跳过测试和中断。

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

That way if you do need to do the process on more than one element your code won't break (pun intended). 这样,如果您确实需要在多个元素上执行该过程,您的代码将不会中断(双关语)。

My preference is to simply use a break . 我的偏好是简单地break It's quick and typically doesn't complicate things. 它很快,通常不会使事情复杂化。

If you use a for , while , or do while loop, you can use a variable to determine whether or not to continue: 如果使用forwhiledo while循环,则可以使用变量来确定是否继续:

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

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

The only way to break from a foreach loop is to break or return . foreach循环中断的唯一方法是breakreturn

Use a 用一个

Object object;
int index = 0;

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

if breaking from a for loop makes you feel uneasy. 如果从for循环中断开让你感到不安。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM