2016-03-21 15 views
2

Bugün ArrayCollection :: forAll yöntemini yinelemeli anonim bir işleve karşı kullanırken garip davranışı buldum.ArrayCollection :: forTüm yineleme

ön koşullar:

Ben Post birimlerin bir koleksiyona sahip. Her Post, SocialPost varlıklarından oluşan bir koleksiyon içerir.

Amaç: Tüm Posta ve SocialPost varlıklar "beklemede" için

Seti durumu.

Çözümümün:

ben böyle oldukça basit kapatma kullanabilirsiniz düşündüm:

$setPending = function($_, StatusAwareInterface $post) use (&$setPending) { 
     echo "func entry point reached\r\n"; 
     if ($post instanceof Post) { 
      echo "This is post. SP Count: " . count($post->getSocialPosts()) . "\r\n"; 
      $post->getSocialPosts()->forAll($setPending); 
      $status = Post::STATUS_PENDING; 
     } else { 
      echo "This is SP\r\n"; 
      $status = SocialPost::STATUS_PENDING; 
     } 

     $post->setStatus($status); 
    }; 

    // $post contains 2 Post entities 
    // Each Post entity contains 50+ SocialPost entities 
    $posts->forAll($setPending); 

Sonuç:

Ama çıkış çok garip. ForAll sadece ilk öğeyi kullanır ve sonra keser gibi görünür:

func entry point reached 
This is post. SP Count: 52 
func entry point reached 
This is SP 

Burada kimse sorunu görüyor mu?

cevap

4

en ArrayCollection source

Doc kontrol edelim diyor ki:

 * Applies the given predicate p to all elements of this collection, 
     * returning true, if the predicate yields true for all elements. 

Bu ne demiyor çünkü misleasing olabileceğini yüklem false, tüm işlev forAll dönüşü falsehemen dönerse. en kaynağında bir göz atalım:

public function forAll(Closure $p) 
{ 
    foreach ($this->elements as $key => $element) { 
     if (! $p($key, $element)) { // <-- here's null converted to false. 
      return false; 
     } 
    } 

    return true; 
} 

İşleviniz null olan şey, döndürmez. Daha ileride, null, 'a dönüştürülür, forAll yönteminin neden olduğu, ArrayCollection numaranız üzerinde yineleme tamamlanmadan önce kesilir.

bir çözüm olarak en ve anonim fonksiyonun hattını

return true; 

eklemek gerekir.

Ek not: forAll

onay koleksiyonunda her eleman her bir öğesi için koşul

ve

yapamaz şey eşleşirse olarak anlaşılması gereken olmalıdır koleksiyon

Bunu doğru yapmak isterseniz, foreach döngüsünü yapmanız yeterlidir.

+0

Evet, haklısınız. Tam olarak array_walk gibi çalıştığını varsayarak bu yöntemi kullanıyordum. Teşekkür ederim. – Hast