0

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!

9
  • There isn't a specific function to cope with the various combinations you want, you will need to write something yourself. Commented Apr 19, 2020 at 6:00
  • How do you decide not to merge all the values with c_id = 51 or c_id = 52 together? Commented Apr 19, 2020 at 6:03
  • It’s only d_id that takes precedence and , is present in one or two values. So, if present it will need to find other values which match r_sid. Otherwise it’s always c_id that this array is filled with. Commented Apr 19, 2020 at 6:12
  • @nigel ren: I do understand that it’s a bit more specific but I have been writing my own sub functions do far to finally come to this array. Just can’t work out this last matching. Commented Apr 19, 2020 at 6:13
  • Can you add the code you have so far to the question as it may be easier to complete that than do something completely new (although that may also be suggested). Commented Apr 19, 2020 at 6:16

1 Answer 1

0

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

Sign up to request clarification or add additional context in comments.

1 Comment

@user7616631 no worries. But... it works for the very small example you've given. I don't know how well it will go when you try it on some serious data...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.