Find direct and indirect child in an array

Hello,
  I have an array

 $arr = array("A"=>"B",
                    "B"=>A",
                    "B"=>"C",
                    "D"=>"C",
                    "D=>"A",
                    "C"=>"H",
                    "Z"=>"X");

I need some some help to create a function that take a value and return all direct and indirect value

example"

-- INPUT : B
--Return [ A,C,D,H]

-- INPUT :C
-- return [B,D,H,A,}

SiemensSENAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

zappafan2k2Commented:
Hi SiemensSEN,

in PHP, you can't have duplicate keys in an associative array.  

After fixing the syntax errors in the code you gave above, if you run print_f($arr), you will get
Array
(
    [A] => B
    [B] => C
    [D] => A
    [C] => H
    [Z] => X
)

Open in new window


You will need to use a different solution for this, possibly a multi-dimensional array:
$arr = array("A"=> array("B"),
"B"=> array("A","C"),
"D"=> array("C","A"),
"C"=> array("H"),
"Z"=> array("X") );

Open in new window

which would give you
Array
(
    [A] => Array
        (
            [0] => B
        )

    [B] => Array
        (
            [0] => A
            [1] => C
        )

    [D] => Array
        (
            [0] => C
            [1] => A
        )

    [C] => Array
        (
            [0] => H
        )

    [Z] => Array
        (
            [0] => X
        )

)

Open in new window


I'm not sure exactly what you mean by "indirect" values.  Can you elaborate?  
0
SiemensSENAuthor Commented:
Sorry  and thanks for your response.

I have an array

        $x[0] = array("A"=>"B");
        $x[1] = array("B"=>"A");
        $x[2] = array("B"=>"C");
        $x[3] = array("D"=>"C");
        $x[4] = array("D"=>"A");
        $x[5] = array("C"=>"H");
        $x[6] = array("Z"=>"X");

Given a value find all it relationship (parent -child)

E.G

Find all mapping for "B"

from the array we can see
B maps to A
B maps to C
D maps C --> implies that B->D
C map to H -> implied B-H

So the return value should be [A,C,D,H]
0
Ray PaseurCommented:
This seems to be an unusual and highly theoretical design pattern.  Is this by any chance an academic assignment?
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Ray PaseurCommented:
This will find the child relationships.  Sorry, it's not my best code ever, but it's half of the answer.  To find the parent relationships, I think you can do something swap the keys and values in the sub-arrays of $x and run this segment again.  Then merge the $results arrays, use array_unique() and you should have what you want.  Maybe I will tinker with it a little more after I walk the dog.
<?php // RAY_temp_siemenssen.php
error_reporting(E_ALL);
echo "<pre>";

// TEST DATA FROM THE POST AT EE
$x[0] = array("A"=>"B");
$x[1] = array("B"=>"A");
$x[2] = array("B"=>"C");
$x[3] = array("D"=>"C");
$x[4] = array("D"=>"A");
$x[5] = array("C"=>"H");
$x[6] = array("Z"=>"X");

// WHAT TO LOOK FOR
$target = 'B';

// WORKING VARIABLES
$answer = array($target);
$founds = array();
$signal = TRUE;
$kount  = 0;
while ($signal)
{
    $founds = $answer;
    foreach ($x as $pair)
    {
        // GET THE KEY AND VALUE
        $key = implode(NULL, array_keys($pair));
        $val = implode(NULL, array_values($pair));

        // IF THIS KEY MATCHES THE TARGET
        if ($key == $target)
        {
            $founds[] = $val;
        }

        // IF THIS KEY MATCHES ONE OF THE PREVIOUSLY FOUND TARGETS
        if (in_array($key, $answer))
        {
            $founds[] = $val;
        }
    }

    // ADD THE NEWLY FOUND VALUES
    $answer = $answer + $founds;

    // NORMALIZE BOTH ARRAYS SO THAT WHILE() WILL COMPARE THEM CORRECTLY (SORT MIGHT NOT BE NECESSARY)
    $answer = array_unique($answer);
    sort($answer);
    $founds = array_unique($founds);
    sort($founds);
    if ($answer == $founds) $kount++;

    // A LIMIT ON THE LOOP
    if ($kount > (count($x) / 2) ) $signal = FALSE;
}

// REMOVE THE TARGET ELEMENT FROM THE ARRAY
$result = array_combine($answer, $answer);
unset($result[$target]);

// SHOW THE WORK PRODUCT
var_dump($result);

Open in new window

0
SiemensSENAuthor Commented:
Thanks,

No it is not a school assignment :).

I am writing a telecom application in which I need to find all the  callIDs in a conference call situation. The ID is used to link the calls and it can appear as parent or child .

I was thinking that it will be  recursive function that walk the array and store the result

Thanks again for your help
0
Ray PaseurCommented:
It's semi-recursive.  I'll tinker with the algorithm a little more today.
0
Ray PaseurCommented:
This seems to do the job.   You can see it in action on my server here.
http://www.laprbass.com/RAY_temp_siemenssen.php

Best regards, ~Ray
<?php // RAY_temp_siemenssen.php
error_reporting(E_ALL);


// A FUNCTION TO GET ALL PARENT/CHILD RELATIONSHIPS
function get_relatives($needle, $haystack)
{
    // WORKING VARIABLES
    $answer = array($needle);
    $founds = array();
    $signal = TRUE;

    while ($signal)
    {
        // A STARTING ARRAY AND COUNT
        $founds = $answer;
        $fcount = count($founds);

        // ITERATE OVER EACH PAIR
        foreach ($haystack as $pair)
        {
            // GET THE KEY AND VALUE
            $key = implode(NULL, array_keys($pair));
            $val = implode(NULL, array_values($pair));

            // TEST KEY AND VALUE AGAINST NEEDLE OR PREVIOUS MATCHES
            if ($key == $needle) $founds[] = $val;
            if ($val == $needle) $founds[] = $key;
            if (in_array($val, $answer)) $founds[] = $key;
            if (in_array($key, $answer)) $founds[] = $val;
        }

        // ADD THE NEWLY FOUND VALUES
        $answer = $answer + $founds;

        // NORMALIZE AND COUNT THE ANSWERS
        $answer = array_unique($answer);
        $acount = count($answer);

        // BREAK THE LOOP WHEN NOTHING NEW IS FOUND
        if ($acount == $fcount) $signal = FALSE;
    }

    // REMOVE THE NEEDLE ELEMENT FROM THE ARRAY
    $result = array_combine($answer, $answer);
    unset($result[$needle]);
    return array_values($result);
}


// TEST DATA FROM THE POST AT EE
$x[0] = array("A"=>"B");
$x[1] = array("B"=>"A");
$x[2] = array("B"=>"C");
$x[3] = array("D"=>"C");
$x[4] = array("D"=>"A");
$x[5] = array("C"=>"H");
$x[6] = array("Z"=>"X");


// CREATE ALL POSSIBLE TEST CASES
foreach ($x as $pair)
{
    $key = implode(NULL, array_keys($pair));
    $val = implode(NULL, array_values($pair));
    $big[] = $key;
	$big[] = $val;
}
$big = array_unique($big);


// TEST ALL POSSIBLE TEST CASES
echo "<pre>";
print_r($x);
echo "</pre>";
foreach ($big as $target)
{
    $out = get_relatives($target, $x);
	echo PHP_EOL . "<br/>$target RELATES TO ";
	print_r($out);
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ray PaseurCommented:
Sorry for errors in indentation - apparently EE and my text editor see the meaning of the tab key differently!
0
SiemensSENAuthor Commented:

Thank you very much for your help
0
SiemensSENAuthor Commented:
Thanks you
0
Ray PaseurCommented:
Thanks for the points - it's a great question!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.