Search code examples
phparraysrecursionmappingmerging-data

Loop a 2d array and merge row data if encountered row key is found in previously stored subarray


I want to consolidate an associative array of indexed arrays by merging rows which have an associative key that is in another row's values.

Consider this sample input:

$array = [
    44259 => [50007, 50009, 46372],
    50007 => [50008],
    50009 => [50010],
    66666 => ['no', 'other', 'links'],
    46372 => [46418, 46419, 46421],
    46421 => [146880]
];

Because the values in the 44259-keyed row (50007, 50009, and 46372) exist as keys in the original array, all of the values from those values should be pushed into the 44259-keyed row.

Continuing the same logic, after the 46372-keyed rows have been added to 44259-keyed row, now the 46421-keyed row values should be pushed into the growing 44259-keyed row.

Desired result:

$array = [
    44259 => [
        50007,  // original
        50009,  // original
        46372,  // original
        50008,  // from 50007
        50010,  // from 50009
        50018,  // from 46372
        46419,  // from 46372
        46421,  // from 46372
        146880, // from 46372 -> 46421
    66666 => [
        'no',
        'other',
        'links'
    ]
];

You see, this is somewhat of a recursive task.

I tried this already:

foreach ($array as $cid => $pid) {
    foreach ($pid as $pip) {
        if (isset($array[$pipp])) {
            foreach ($array[$pipp] as $pip) {
                $array[$cid][] = $pip;
                unset($array[$pipp]);
            }
        }
    }
}

But it's not properly collecting the 46372 row's data for the 44259 row.


Solution

  • You could get the first key using array_keys() and reset(). Then you could add values of all array to this key:

    $array = [];
    
    $array[44259] = [50007, 50009, 46372];
    $array[50007] = [50008];
    $array[50009] = [50010];
    $array[46372] = [46418, 46419, 46421];
    $array[46421] = [146880];
    
    $out = [];
    $keys = array_keys($array);
    $first_key = reset($keys); // $first_key = 44259
    foreach ($array as $k => $items) {
      foreach ($items as $val) {
        $out[$first_key][] = $val;
      }
    }
    print_r($out);
    

    Outputs:

    Array
    (
        [44259] => Array
            (
                [0] => 50007
                [1] => 50009
                [2] => 46372
                [3] => 50008
                [4] => 50010
                [5] => 46418
                [6] => 46419
                [7] => 46421
                [8] => 146880
            )
    
    )