Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 258
  • Last Modified:

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,}

0
SiemensSEN
Asked:
SiemensSEN
  • 6
  • 4
1 Solution
 
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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
 
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

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now