skip to Main Content

I have no idea why this question has been marked as a duplicate, because the so-called duplicate is about using array_merge to combine arrays – this question is about combining element trees WITHIN an array.

Is there a way to combine individual elements and their subtrees within a PHP array? For instance, to convert this:

$test = array(
    "EW" => array(313, 1788),
    "SC" => array(670, 860),
    "FR" => array(704, 709),
    "UK" => array(423, 1733)
);

into this:

$test1 = array(
    "UK" => array(313, 423, 670, 860, 1733, 1788),
    "FR" => array(704, 709)
);

where the entries for EW and SC have been combined with those for UK.

array_combine and array_merge seem to work between arrays, not within them, so I’m not clear how to approach this.

3

Answers


  1. Chosen as BEST ANSWER

    The function {array_merge_trees} will take an array, cut out the trees to be merged and merge them, remove them from the original array, and join the merged trees to what is left of the original array:

    function array_merge_trees($original)
    // Merge individual trees within an array.  
    {
        $mergeme=array(UK, EW, SC, NI, DE, ES, FR, IT);  //The trees you want to merge.  IMPORTANT: The trees must exist within the original array, or you will get empty trees in the joined array.
        $trim=array_flip($mergeme);  // Convert the $mergeme values to keys.
        extract(array_intersect_key($original, $trim));  // Extract the trees in $mergeme - they will each become an array named after the key, eg $UK, $EW.
        $merged['UK']=array_merge($UK, $EW, $SC, $NI);  // Merge extracted trees as an element of a new array. IMPORTANT: The trees listed here must exist within the original array, or you will get empty trees in the joined array.
        sort($merged['UK']);  // Sort the values of the merged tree.
        // Repeat the above two lines if you want further merges, eg:
        $merged['EU'] = array_merge($DE, $ES, $FR, $IT);
        sort($merged['EU']);
        $trimmed=array_diff_key($original, $trim);  // Remove the trees to be merged from the original array.
        $rejoined=array_merge($trimmed, $merged);  // Join the merged trees with the non-merged trees from the original array.
        ksort($rejoined);  // Sort the keys of the rejoined array.
        return $rejoined;
    }
    

    To use it:

    $original=array("EW"=>array(313, 1788), "SC"=>array(670, 860), "FR"=>array(704, 709), "UK"=>array(423, 1733), "DE"=>array(220, 260), "ES"=>array(1346, 1229), "NI"=>array(410, 453), "IT"=>array(134, 988));
    
    $original=array_merge_trees($original);
    
    echo "<pre>";
    print_r($original);
    echo "</pre>";
    

    EDIT: Honk's answer is much better than this one.


  2. One way to do it will be like this:

    $test=array("EW"=>array(313, 1788), "SC"=>array(670, 860), "FR"=>array(704, 709), "UK"=>array(423, 1733));
    
    //extract function converts all the keys to variables. 
    
    extract($test);
    $newarray['UK'] = array_merge($EW,$SC,$UK) ;
    $newarray['FR'] = $FR;
    
    
    
    echo "<pre>";
    print_r($newarray);
    echo "</pre>";
    

    The result:

    Array
    (
        [UK] => Array
            (
                [0] => 313
                [1] => 1788
                [2] => 670
                [3] => 860
                [4] => 423
                [5] => 1733
            )
    
        [FR] => Array
            (
                [0] => 704
                [1] => 709
            )
    
    )
    

    For small use case where you know the key and it will not change this method is ok …

    Login or Signup to reply.
  3. You’ll have to make a map of keys that have to be grouped with another key ($group_keys in the code below)

    $test= [
        'EW' => [313, 1788], 
        'SC' => [670, 860], 
        'FR' => [704, 709], 
        'UK' => [423, 1733]
    ];
    
    $group_keys=[
        'EW' => 'UK', 
        'SC' => 'UK'
    ];
    
    $result = [];
    foreach($test as $code => $values) {
        if (isset($group_keys[$code])) {
            $target = $group_keys[$code];
        }
        else {
            $target = $code;
        }
        if (isset($result[$target])) {
            $result[$target] = array_merge($result[$target], $values);
        }
        else {
            $result[$target] = $values;
        }
    }
    
    print_r($result);
    

    Output:

    Array
    (
        [UK] => Array
            (
                [0] => 313
                [1] => 1788
                [2] => 670
                [3] => 860
                [4] => 423
                [5] => 1733
            )
    
        [FR] => Array
            (
                [0] => 704
                [1] => 709
            )
    
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search