Php 对于每个。。。打破

Php 对于每个。。。打破,php,javascript,foreach,Php,Javascript,Foreach,每次我“打破”一个for-each结构(PHP/Javascript)时,我都会感到脏兮兮的 比如说: //Javascript示例 for (object in objectList) { if (object.test == true) { //do some process on object break; } } 对于大型对象列表,我将经历构建更优雅的解决方案的麻烦。但是对于小列表来说,没有明显的性能问题,因此“为什么不呢?”很快,更重要的是

每次我“打破”一个for-each结构(PHP/Javascript)时,我都会感到脏兮兮的

比如说:

//Javascript示例

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

}
对于大型对象列表,我将经历构建更优雅的解决方案的麻烦。但是对于小列表来说,没有明显的性能问题,因此“为什么不呢?”很快,更重要的是很容易理解和遵循

但它只是“感觉不对”。有点像goto语句


你是如何处理这种情况的?

我利用休息时间。这是一个完美的解决方案。

我真的不认为打破for循环有什么错。除非你有某种哈希表、字典,在字典里你有某种键来获取一个值,否则真的没有其他方法。

我会使用
break
语句。

对于小列表,这样做没有问题。 正如您所提到的,您可能想为大型列表(尤其是大小未知的列表)考虑一个更“优雅”的解决方案

有时候感觉不对,但没关系。你会及时学会爱
打破

就像你说的“为什么不呢?”它很快,更重要的是很容易理解和理解。”


为什么感觉脏,我看不出这有什么错。

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

它应该是这样的。Break设计为跳出一个循环。如果你已经在循环中找到了你需要的东西,为什么还要继续循环

也许我误解了您的用例,但为什么要中断呢?我假设您希望列表中最多有一个元素的测试为真

如果没有性能问题,并且您希望清理代码,那么您可以随时跳过测试和中断

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

这样,如果您确实需要在多个元素上执行此过程,您的代码将不会中断(双关语)。

我的首选是简单地使用
中断。它很快,通常不会使事情复杂化

如果将
用于
while
do while
循环,则可以使用变量确定是否继续:

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

    if ($condition) {
        $c= false;
    }
}
for($i=0,$c=true;($i<10)和&$c;$i++){
//做事
如果($条件){
$c=假;
}
}
foreach
循环中断的唯一方法是
break
return

它很快,更重要的是易于理解和遵循


不要为休息感到难过。后进是不受欢迎的,因为它很快,更重要的是不容易理解和遵循。

中断和继续不是后进。他们在那里是有原因的。完成循环结构后,立即退出循环

现在,我要避免的是非常非常深的嵌套(也称为箭头设计反模式)

如果你想休息一下,那就确保你的代码结构只有一层深。使用函数调用使迭代尽可能浅

if (someCondition)
{
    loopThroughCollection(collection);
}

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

function doSomethingToObject(thing)
{
    // etc.
}
使用


如果从
for
循环中断会让您感到不安。

请看,中断根本不会让我感到不安。编程是建立在goto之上的,而for break——就像所有的控制结构一样——只是一种特殊用途的goto形式,旨在提高代码的可读性永远不要为编写可读代码感到难过


现在,我确实对直接比较
true
感到不快,尤其是在使用类型转换相等运算符时。。。哦,是的。您所编写的-
if(object.test==true)
-与编写
if(object.test)
相当,但需要更多的思考。如果您确实希望只有当
object.test
既是布尔值又是
true
时,比较才会成功,那么您应该使用。。。否则,跳过它。

一般来说,
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
语句从常规代码库推到一个helper函数中。

我知道你在说什么,但每个人都在正确的轨道上——break很好,特别是对于小列表。我的大列表通常来自DB查询,如果必须的话,我会使用LIMIT函数只提取记录的子集。简短的回答——不要为使用“break”或“continue”感到难过,因为for..in运算符将始终迭代对象的键(字符串)。您的意思可能是这样的:对于(objectList中的var key){var object=objectList[key];…}我这样做,尽管通常只使用
while
循环?这可能不是更好的解决方案,但至少是另一种方法;)我从未声称添加另一个变量是我的偏好。这是一个选择。我不确定你的回答是否值得投反对票。我对你所写的唯一的问题是,它不允许你在问题出现的时候,对一个关联的对象数组进行注释。我喜欢“cromulent”的意思是它是什么意思-一个从上下文中很明显的词。通过这个论点,你可以删除这个词,只留下上下文,从而进一步澄清这个句子。节省字节太多@Leigh:“这是一个完美的解决方案”?我接受你的答案纯粹是为了教我一个新的,尽管是流行的单词。我很高兴增加你的词汇量。从前,当我开始编程时
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
  }
}