Syn c значения массива по всем связанным ключам массива - PullRequest
0 голосов
/ 02 марта 2020

У меня есть массив PHP со следующими данными

Array
(
    [3] => Array
        (
            [0] => 4095
            [2] => 651
        )

    [4095] => Array
        (
            [0] => 3
        )

    [651] => Array
        (
            [0] => 4432
        )

    [4432] => Array
        (
            [0] => 651
        )
    [92] => Array
        (
            [0] => 45
        )
)

Вышеуказанный массив имеет ключи как student_id, а значения также student_id создают круговое отношение. Я пытаюсь достичь того, чтобы все student_id имели одинаковый набор student_id значений. В основном, если student_id 3 относится к 4095, 4432 & 651, то, в свою очередь, каждое из этих значений должно иметь среди них 3, включая другие student_id из 3. Приведенный ниже вывод демонстрирует, чего я пытаюсь достичь.

Array
(
    [3] => Array
        (
            [0] => 4095
            [1] => 4432
            [2] => 651
        )

    [4095] => Array
        (
            [0] => 3
            [1] => 4432
            [2] => 651
        )

    [651] => Array
        (
            [0] => 3
            [1] => 4432
            [2] => 4095
        )

    [4432] => Array
        (
            [0] => 3
            [1] => 4095
            [2] => 651
        )
    [92] => Array
        (
            [0] => 45
        )
    [45] => Array
        (
            [0] => 92
        )
)

Объяснение выходных данных

Ключи массива 3, 4095, 651 & 4432 связаны с друг друга либо напрямую, либо через общее отношение (косвенное), поэтому будет иметь общий набор значений (родные братья). Ключ 92 во входном массиве имеет значение (одноуровневое) 45, поэтому в результирующем массиве новый ключ 45 будет добавлен в массив также с обратным соотношением.

Что Я пытался до сих пор

Я пытался сделать это с этим кодом

$syncedSiblings = [];
        foreach ($studentsWithSiblings as $sid => $siblings) {
            $all = map_assoc(array_merge([$sid], array_keys($siblings)));
            foreach ($all as $studentId) {
                if (isset($syncedSiblings[$studentId])) {
                    $old = $syncedSiblings[$studentId];
                    $syncedSiblings[$studentId] = array_unique(array_merge($old, array_except($all, $studentId)));
                } else {
                    $syncedSiblings[$studentId] = array_unique(array_except($all, $studentId));
                }
            }
        }

Где $studentsWithSiblings имеет вышеуказанный массив & array_except возвращает массив без переданных значений в качестве второго аргумента ,

Это вывод, который я сейчас получаю

Array
(
    [3] => Array
        (
            [0] => 4095
            [1] => 651
        )

    [4095] => Array
        (
            [0] => 3
            [1] => 651
        )

    [651] => Array
        (
            [0] => 3
            [1] => 4095
            [2] => 4432
        )

    [4432] => Array
        (
            [0] => 651
        )
    [92] => Array
        (
            [0] => 45
        )

)

Любая помощь с этим будет высоко оценена.

Ответы [ 2 ]

1 голос
/ 02 марта 2020

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

function getChildren($ind_ar, $prev_ar, $data, $rem){

    $tmp = [];
    $mark = 0;
    foreach($ind_ar as $ind){

        foreach($data[$ind] as $new_val){

            if(!in_array($new_val,$prev_ar) && $new_val != $ind && $new_val != $rem){

                $mark = 1;
                $tmp[] = $new_val;
            }

            foreach($data[$new_val] as $new){
                if(!in_array($new,$prev_ar) && $new != $ind && $new != $rem){

                    $mark = 1;
                    $tmp[] = $new;
                }
            }
        }
    }

    $res_ar = $prev_ar;

    if(!empty($tmp)) $res_ar = array_unique(array_merge($tmp,$prev_ar));  
    if($mark) $res_ar = getChildren($tmp,$res_ar,$data, $rem);   

    return $res_ar;
}  

Вы можете использовать эту функцию следующим образом:

$data = array( 3 => [4095, 651], 4095 => [3], 651 => [4432], 4432 => [3, 651], 92 => [45], 45 => [92], );

foreach($data as $in => &$data_val) { 
    $data_val = getChildren([$in],$data_val,$data, $in);
    sort($data_val);
}

Демо

Выход:

Array
(
    [3] => Array
        (
            [0] => 651
            [1] => 4095
            [2] => 4432
        )

    [4095] => Array
        (
            [0] => 3
            [1] => 651
            [2] => 4432
        )

    [651] => Array
        (
            [0] => 3
            [1] => 4095
            [2] => 4432
        )

    [4432] => Array
        (
            [0] => 3
            [1] => 651
            [2] => 4095
        )

    [92] => Array
        (
            [0] => 45
        )

    [45] => Array
        (
            [0] => 92
        )

)
0 голосов
/ 02 марта 2020

Два вложенных цикла над данными. Если ключи разные, то проверьте, содержится ли уже ключ внутреннего l oop в массиве данных элемента внешнего ключа - если нет, добавьте его.

$data = json_decode('{"3":{"0":4095,"2":651},"4095":[3],"651":[4432],"4432":{"1":651}}', true);

foreach($data as $key_outer => $val_outer) {
  foreach($data as $key_inner => $val_inner) {  
    if($key_outer != $key_inner && !in_array($key_inner, $data[$key_outer])) {
      $data[$key_outer][] = $key_inner;
    }
  }
}

var_dump($data);

Это вам

array (size=4)
  3 => 
    array (size=3)
      0 => int 4095
      2 => int 651
      3 => int 4432
  4095 => 
    array (size=3)
      0 => int 3
      1 => int 651
      2 => int 4432
  651 => 
    array (size=3)
      0 => int 4432
      1 => int 3
      2 => int 4095
  4432 => 
    array (size=3)
      1 => int 651
      2 => int 3
      3 => int 4095

Я предполагаю, что определенный c порядок элементов в этих подпунктах фактически не требуется. Если это так, то, пожалуйста, сортируйте их по своему желанию впоследствии или между ними (в зависимости от того, что именно вам нужно, например, sort($data[$key_outer]); после внутреннего l oop даст вам идентификаторы во всех подмассивах, отсортированных по возрастанию.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...