phparraysmultidimensional-arrayarray-mergearray-combine

PHP Array combine values with same string key


I have the following issue that seems common but can't figure out which array function might work for the following format:

(Already tried array_merge , array_merge_recursive , array_combine, array_splice but didn't work as expected.)

Array
(
    [0] => Array
        (
            [r_id] => 11
            [r_sid] => RC
            [d_id] => 2
        )

    [1] => Array
        (
            [r_id] => 7
            [r_sid] => RC
            [c_id] => 51
        )

    [2] => Array
        (
            [r_id] => 6
            [r_sid] => JN
            [c_id] => 52
        )

    [3] => Array
        (
            [r_id] => 7
            [r_sid] => JN
            [c_id] => 51
        )

    [4] => Array
        (
            [r_id] => 7
            [r_sid] => LG
            [c_id] => 51
        )

    [5] => Array
        (
            [r_id] => 7
            [r_sid] => BN
            [c_id] => 51
        )

    [6] => Array
        (
            [r_id] => 6
            [r_sid] => IVS
            [c_id] => 52
        )

    [7] => Array
        (
            [r_id] => 7
            [r_sid] => IVS
            [c_id] => 51
        )

)

Now, I need to merge this array values by common r_sid & c_id keys; The only special case scenario is if there is a d_id key instead of c_id then we merge/combine that with any value in the array that has similar r_sid.

The final solution needs to look like this, if thats easier to understand:

Array
(
    [0] => Array
        (
            [r_id] => 11,7
            [r_sid] => RC
            [d_id] => 2
            [c_id] => 51 
        )


    [1] => Array
        (
            [r_id] => 6,7
            [r_sid] => JN, IVS
            [c_id] => 52,51
        )

)

The r_sid values that do not match with anyone needs to be discarded.

Any help is appreciated. Many thanks!


Solution

  • Here's a piece of code that is my best interpretation of how to merge your array:

    // filter out r_sid values which only occur once
    $sid_values = array_count_values(array_column($array, 'r_sid'));
    $array = array_filter($array, function ($a) use ($sid_values) { return $sid_values[$a['r_sid']] > 1; });
    
    // combine arrays on r_sid values
    $result = array();
    foreach ($array as $arr) {
        $sid = $arr['r_sid'];
        // push data to arrays
        $result[$sid]['r_sid'] = $sid;
        $result[$sid]['r_id'][] = $arr['r_id'];
        if (isset($arr['c_id'])) $result[$sid]['c_id'][] = $arr['c_id'];
        if (isset($arr['d_id'])) $result[$sid]['d_id'][] = $arr['d_id'];
    }
    
    // combine all the c_id values into a string
    array_walk($result, function (&$a) {
        if (isset($a['c_id'])) $a['c_id'] = implode(',', $a['c_id']);
    });
    
    // now combine any r_sid values that have the same set of c_id values
    $output = array();
    foreach ($result as $res) {
        $cid = $res['c_id'];
        // push data to arrays
        $output[$cid]['c_id'] = $cid;
        $output[$cid]['r_sid'] = array_merge($output[$cid]['r_sid'] ?? array(), array($res['r_sid']));
        $output[$cid]['r_id'] = array_merge($output[$cid]['r_id'] ?? array(), $res['r_id']);
        if (isset($res['d_id'])) $output[$cid]['d_id'] = array_merge($output[$cid]['d_id'] ?? array(), $res['d_id']);
    }
    
    // combine the r_sid, r_id and d_id values into a string
    array_walk($output, function (&$a) {
        $a['r_sid'] = implode(',', $a['r_sid']);
        $a['r_id'] = implode(',', array_unique($a['r_id']));
        if (isset($a['d_id'])) $a['d_id'] = implode(',', $a['d_id']);
    });
    
    // remove the associative keys
    $output = array_values($output);
    

    Output:

    Array
    (
        [0] => Array
            (
                [c_id] => 51
                [r_sid] => RC
                [r_id] => 11,7
                [d_id] => 2
            )
        [1] => Array
            (
                [c_id] => 52,51
                [r_sid] => JN,IVS
                [r_id] => 6,7
            )
    )
    

    Demo on 3v4l.org