Avatar billede Slettet bruger
28. april 2008 - 22:34 Der er 8 kommentarer og
1 løsning

dynamisk lookup i multidimentionalt array

Hej Experter!

Jeg har følgende array:

$myarr = array();

$myarr["level_0"] = array(
   
    "task" => "eat",   
    "level_1" => array(       
        "name" => "john",
        "surname" => "doe",               
        "level_2" => array(
            "veggy" => "potatoes",
            "meat" => "beef",
            "source" => "white",           
            "level_3" => array(
                "desert" => array("cheese" => "danablue")
            )
        ) 
    )
);

----

Følgende funktion finder den nøjagtige "path" til hvorhenne en given key er henne recursivt i dette array.

function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
{
    if( !is_array($haystack) )
    {
        return false;
    }

    foreach( $haystack as $key => $val )
    {
        if( is_array($val) && $subPath = array_searchRecursive($needle, $val, $strict, $path) )
        {
            $path = array_merge($path, array($key), $subPath);
            return $path;
        }
        elseif( (!$strict && $key == $needle) || ($strict && $key === $needle) )
        {
            $path[] = $key;
            return $path;
        }
    }
    return false;
}

----

For eksempel hvis jeg leder efter:

$result = array_searchRecursive("cheese", $myarr);

vil ovenstående funktion returnere et array med alle keys til "cheese"

result Array
(
    [0] => level_0
    [1] => level_1
    [2] => level_2
    [3] => level_3
    [4] => desert
    [5] => cheese
)

----

For at finde ud af hvilken ost "john doe" vil ha til desert, kunne man skrive:

echo $myarr["level_0"]["level_1"]["level_2"]["level_3"]["desert"]["cheese"]

og få responsen: "danablue"

----

Mit spørgsmål er nu: hvordan laver jeg programmatisk et forloop lookup i arrayet "$myarr" udfra dette resultat array? - Jeg vil IKKE bruge eval.


På forhånd tak!

:-)
Avatar billede pidgeot Nybegynder
29. april 2008 - 11:05 #1
Det er med andre ord "stien" til værdien du har der? I så fald starter du med at tildele dit array til en anden variabel, og henter et niveau ad gangen ud i den samme variabel.

Eksempel:
$res = $myarr;
foreach ($arr as $arrval)
  $res=$res[$arrval];
Avatar billede Slettet bruger
29. april 2008 - 13:49 #2
Hej Pidgeot...

Det er "stien" til osten ja, fuldstændigt korrekt

Men desværre så trivielt er det ikke.

man bliver nødt til at concatenate alle keys som du rigtigt angiver, men efter første gennemløb vil det fejle og give illigal offset type - for hver iteration overskriver du key og dermed angiver et offset som ikke eksisterer...
Avatar billede pidgeot Nybegynder
29. april 2008 - 14:33 #3
Det er da vist ikke baseret på at teste den. *-)

Princippet virker netop fordi jeg overskriver den variabel jeg henter fra. I $myarr["level_0"]["level_1"] er ["level_1"] jo en key i det array der ligger som $myarr["level_0"]. Ved at hente $myarr["level_0"] ud i en variabel, vil man derfor kunne hente $myarr["level_0"]["level_1"] med $nyvar["level_1"].

Det samme gør sig naturligvis gældende længere nede i arrayet.

Min foreach svarer dermed til følgende tildelinger:

$res = $myarr;
$res = $res["level_0"]; //$res = $myarr["level_0"];
$res = $res["level_1"]; //$res = $myarr["level_0"]["level_1"];
$res = $res["level_2"]; //$res = $myarr["level_0"]["level_1"]["level_2"];
...og så videre.

Demo på http://birdiesoft.dk/exp829582.php
Avatar billede Slettet bruger
29. april 2008 - 14:41 #4
Du har da fuldstændigt ret! - Det virker jo perfekt!

Jeg tænkte nok at det bare var en lille fidus der skulle til - har været ude i alskins afkroge og snask på php.net.... tusind tak! :-)

Smid et svar så giver jeg dig dine super-velfortjente points.
Avatar billede pidgeot Nybegynder
29. april 2008 - 14:52 #5
S'gerne :)
Avatar billede Slettet bruger
29. april 2008 - 15:04 #6
Endnu engang tusind tak, du har reddet mig for at komme til at ligne Volborg ;-)
Avatar billede Slettet bruger
30. april 2008 - 16:26 #7
pidgeot, hvis jeg nu skulle opdatere værdien af cheese til "gamle ole" dynamisk, skulle du måske have et lille fif til IKKE at overskrive $res variablen, men derimod bare addere stien?

DVS når foreach loopet er færdig, så er det ikke strengen "danablue" men derimod selve array index'et dybt ind i arrayet så man kan gøre dette:

$res["cheese"] = "gamle ole";

altså lig med:

$res["level_0"]["level_1"]["level_2"]["level_3"]["desert"]["cheese"] = "gamle ole";

Igen tak for din hjælp :-)
Avatar billede pidgeot Nybegynder
30. april 2008 - 17:57 #8
Det kunne du jo bare have sagt at du ville *-)

I den situation bør du i stedet kunne sætte et &-tegn umiddelbart efter =-tegnene (både den umiddelbart før loopet, og den inde i loopet) - dette vil lave $res om til en reference, og en ændring af den skulle derfor også ændre $myarr[...].
Avatar billede Slettet bruger
30. april 2008 - 19:15 #9
Skal skam bruge begge dele :-)

// SET
$res =& $myarr;

foreach($result as $arrval)
{
    $res =& $res[$arrval];
}

$res = "gamle ole";

echo "<pre>";
print_r($myarr);
echo "</pre>";

Det er jo ren trylleri - endnu engang tak!!!!!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester