PHP Массив объединяет значения с одним и тем же строковым ключом - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть следующая проблема, которая кажется распространенной, но я не могу понять, какая функция массива могла бы работать для следующего формата:

(уже пробовали array_merge, array_merge_recursive, array_combine, array_splice но работает не так, как ожидалось.)

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
        )

)

Теперь мне нужно объединить значения этого массива общими r_sid & c_id ключами; Единственный особый сценарий - если вместо c_id есть ключ d_id, то мы объединяем / объединяем его с любым значением в массиве, имеющим аналогичный r_sid.

Окончательное решение должно выглядеть следующим образом, если это легче понять:

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
        )

)

Значения r_sid, которые не соответствуют никому, необходимо отбросить.

Любая помощь приветствуется. Большое спасибо!

1 Ответ

0 голосов
/ 20 апреля 2020

Вот фрагмент кода, который является моей лучшей интерпретацией того, как объединить ваш массив:

// 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);

Вывод:

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

Демонстрация на 3v4l.org

...