Belli bir kimliği için çok boyutlu bir dizi bir yol bulma

4 Cevap php

Bu gibi saklanan bir dizi var:

[0] => Array
    (
        [id] => 1
        [cat_name] => c1
    )

[1] => Array
    (
        [id] => 2
        [cat_name] => c2
        [copii] => Array
            (
                [0] => Array
                    (
                        [id] => 5
                        [cat_name] => c21
                    )

                [1] => Array
                    (
                        [id] => 6
                        [cat_name] => c22
                    )

            )

    )

[2] => Array
    (
        [id] => 3
        [cat_name] => c3
        [copii] => Array
            (
                [0] => Array
                    (
                        [id] => 7
                        [cat_name] => c31
                        [copii] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 9
                                        [cat_name] => c311
                                    )

                            )

                    )

                [1] => Array
                    (
                        [id] => 8
                        [cat_name] => c32
                    )

            )

    )

I'm trying to find an easier way of finding a route to a certain ID. Now I'm using foreach to iterate through all possible arrays and finding the route.

Örnek:

id = 1:
     route[0][id]=1,route[0][cat_name]=c1
id = 5:
    route[0][id]=2,route[0][cat_name]=c2
    route[1][id]=5,route[1][cat_name]=c21
id = 9:
    route[0][id]=3,route[0][cat_name]=c3
    route[1][id]=7,route[1][cat_name]=c31
    route[2][id]=9,route[2][cat_name]=c311

Benim sorum hiçbir mantıklı olursa, ben ona güzel bir çözüm bulmaya çalışırken harcanan saatleri suçu ...

4 Cevap

Kod bir grup gönderme yerine, ben bunu bilmem eğer özyinelemenin kadar okuyun öneririm. PHP özyineleme anda çok büyük değil, ama bu gerçekten tek seçenek bulunuyor.

Temelde dizi bulmak için id, ve yolu temsil eden bir dize / dizisi alır bir işlevi çağırır. Başlangıçta boş bir dize veya ikinci parametre için boş dizi diyoruz.

Fonksiyonu bunu yapardı:

  • $array en üst düzeyi ile bir foreach çalıştırın
  • Eğer $id arıyorsanız bulursanız, $path return.
  • Dizi değerlerden biri bir alt dizi ise, geçerli kimlik düğümü eklemek ve tekrar işlevini çağırmak - $foundPath = findPath( $array, $id, $path ) gibi bir şey.
  • $foundPath şey dönerse, o zaman yol var ve dönebilirsiniz.
  • O ($foundPath aşağıdaki gibi yanlış veya null) bir şey bulamadıysanız, bırakın ve döngünün sonraki yineleme geçmek.
  • Eğer bir şey bulamadım eğer döngünün sonunda, yanlış veya boş dönmek.

Umarım ki olur!

Özyineleme ne istiyorsun:

<?php

    function walk_array(array $a, &$ra, $path, $depth = 0) {
     $id= isset($path[$depth]) ? $path[$depth] : null;
     if (!is_null($id)) {
      foreach ($a as $a2) {
       if ($a2['id'] == $id) {
        $ra[$depth]= $a2;
        unset($ra[$depth]['copii']);
        // This is the key bit - recursion is simply a function calling itself:
        if (isset($a2['copii']))
         walk_array($a2['copii'], $ra, $path, ++$depth);
       }
      }
     }
    }

    $complex_array= array(
      array('id'=> 1, 'name'=> 'Node #1', 'copii'=> array(
       array('id'=> 3, 'name'=> 'Node #3', 'copii'=> array(
         array('id'=> 4, 'name'=> 'Node #4')
       ))
      )),
      array('id'=> 2, 'name'=> 'Node #2', 'copii'=> array(
       array('id'=> 5, 'name'=> 'Node #5', 'copii'=> array(
         array('id'=> 6, 'name'=> 'Node #6',)
       ))
      )),
    );    

    // Prints out nodes 1,3,4 in order
    $ra= array();
    walk_array($complex_array, $ra, array(1, 3, 4));
    print_r($ra);

    // Prints out nodes 2,5,6 in order
    $ra= array();
    walk_array($complex_array, $ra, array(2, 5, 6));
    print_r($ra);

    // Prints out empty array
    $ra= array();
    walk_array($complex_array, $ra, array(5, 2, 4));
    print_r($ra);

    // Prints out nodes 2,5 in order
    $ra= array();
    walk_array($complex_array, $ra, array(2, 5));
    print_r($ra);
?>

Sizin soru gerçekten hiçbir mantıklı. Ne demek "yol bulma" nedir?

Diziniz bir grafik anlatan bir özyinelemeli yapıya sahip gibi görünüyor; kısa yolu bulmak için bir grafik kastetmek algoritma (- belki bir düğüm listesi + kenar listesi, ve bunun üzerine algoritmalar bir grafik çalıştırmak yani bir grafik veri yapısı içine diziyi dönüştürme) daha uygun olabilir.

Aklıma Bir diğer yol - özyinelemeye kaçınarak - "değişken değişkenleri" kullanmaktır, böylece sadece bir noktaya kadar, dizi indisleri her olası birleşimini deneyin.

$search = 3;
$ind = '$arr[0][copii][1]'; // generated somehow
if ( isset(${$ind}['id']) && ${$ind}['id'] == $search ) {
  // we found it
}

Bu sadece uzun sürer ve bir şey bulmak için garanti değil. Ben bunu yazmak da, ben ayrı özyineleme gelen ... $ind değerlerini oluşturmak için sağlam bir yol düşünmek için mücadele ediyorum. Ben 000, 001, 002 gibi 3 basamaklı sayılar üretmek ve $arr[0][copii][0][copii][0], $arr[0][copii][0][copii][1] ve $arr[0][copii][0][copii][2] gibi endeksleri oluşturmak için her karakteri kullanabilirsiniz sanırım.

Şüphesiz değerleri özledim ve var olmayan değerlerin bir yeri aramak için, bu yöntem hala mükemmel değil. Dürüst olmak gerekirse, özyineleme olan basit ve temiz bir seçenek kod-bilge, ve dizi girdileri yüzlerce olmadıkça o zaman büyük bir performans sorunu fark etmeyeceğiz.