php排序/移动对象并加入/删除相同的对象

时间:2014-05-01 18:19:11

标签: php arrays foreach unset

首先,它非常类似于“Unsetting elements from array within foreach

但是我不知道它周围的方式。有没有办法将foreach循环中的项标记为“已使用”或“已删除”?

我基本上有一些对象数组,它们在某些对象属性中是相似的,但不完全相同。我想加入类似对象的信息。这个想法如下

  1. 通过选择一个对象来浏览数组
  2. 每个拾取的对象再次通过数组并找到类似的
  3. 一旦找到类似的,加入信息并删除类似的对象
  4. 就是这样。

    它有点预期,但有一个问题(像往常一样:-)。它来了:

    虽然我在第二个循环中删除了类似的对象。第一个循环仍在拾取已删除的对象。这似乎是因为foreach在数组的某种副本上循环。

    对于讨论/演示,我通过查看字符串并加入它们来采用如下代码。假设我们有一个像这样的数组

    $test = array( "a", "b", "c", "b", "c" );
    

    预期结果:

    array( "a", "bb", "cc" );
    

    以下是代码:

    $test = array( "a", "b", "c", "b", "c" );
    
    foreach ($test as $keyA=>$valueA){
      echo "I am at item ".$valueA." [".$keyA."]<br>";
    
      foreach ($test as $keyB=>$valueB){
    
        if ($keyA != $keyB){
          // if not comparing to itself
          echo "=> comparing to ".$valueB." [".$keyB."]";
    
          if (strcmp($valueA,$valueB)==0){
            // is the same string, ... join and remove
            echo "-- joined and removed [".$keyB."]";
            $test[$keyA]=$valueA.$valueB;
            unset($test[$keyB]);      
          }
          echo "<br>";
        }
      }
    
    }
    

    和实际结果

    I am at item a [0]
    => comparing to b [1]
    => comparing to c [2]
    => comparing to b [3]
    => comparing to c [4]
    I am at item b [1]
    => comparing to a [0]
    => comparing to c [2]
    => comparing to b [3]-- joined and removed [3]
    => comparing to c [4]
    I am at item c [2]
    => comparing to a [0]
    => comparing to bb [1]
    => comparing to c [4]-- joined and removed [4]
    I am at item b [3]
    => comparing to a [0]
    => comparing to bb [1]
    => comparing to cc [2]
    I am at item c [4]
    => comparing to a [0]
    => comparing to bb [1]
    => comparing to cc [2]
    

    虽然删除了第[3]和[4]项,但它仍在选择[3]和[4]。

1 个答案:

答案 0 :(得分:0)

是的,foreach循环正在处理副本,但是当你调用unset()时,你实际上仍然没有设置该元素,即使你没有更改foreach循环迭代的副本。 ..所以即使实际数组已被更改,foreach循环也不知道,可以这么说......你可以简单地将这个检查添加到你的代码中,如果该元素未被设置则跳过迭代:

foreach ($test as $keyA=>$valueA){

    if (!isset($test[$keyA])) continue;     

    echo "I am at item ".$valueA." [".$keyA."]<br>";

    // etc...
}

输出变成了这个,如果我理解你的问题是你正在寻找的东西:

I am at item a [0]
=> comparing to b [1]
=> comparing to c [2]
=> comparing to b [3]
=> comparing to c [4]
I am at item b [1]
=> comparing to a [0]
=> comparing to c [2]
=> comparing to b [3]-- joined and removed [3]
=> comparing to c [4]
I am at item c [2]
=> comparing to a [0]
=> comparing to bb [1]
=> comparing to c [4]-- joined and removed [4]