2017-01-27 12 views
2

Я пытаюсь получить все возможные комбинации для неизвестного числа массивов, как например:Получить все уникальные комбинации массива с помощью декартова PHP продукта

Вот Структура данных JSON

[ 
    { 
     "department": "CIS", 
     "name": "Intro to CIS", 
     "sections": [ 
      { 
       "sectionNumber": "01", 
       "regNum": "", 
       "days": "MWF", 
       "startTime": "900", 
       "endTime": "1030", 
       "labDay": "M", 
       "labStartTime": "1300", 
       "labEndTime": "1500" 
      }, 
      { 
       "sectionNumber": "02", 
       "regNum": "098304", 
       "days": "TR", 
       "startTime": "1300", 
       "endTime": "1500", 
       "labDay": "", 
       "labStartTime": "", 
       "labEndTime": "" 
      } 
     ] 
    }, 
    { 
     "department": "MATH", 
     "name": "Intro to MATH", 
     "sections": [ 
      { 
       "sectionNumber": "01", 
       "regNum": "", 
       "days": "MWF", 
       "startTime": "900", 
       "endTime": "1030", 
       "labDay": "M", 
       "labStartTime": "1300", 
       "labEndTime": "1500" 
      }, 
      { 
       "sectionNumber": "02", 
       "regNum": "098304", 
       "days": "TR", 
       "startTime": "1300", 
       "endTime": "1500", 
       "labDay": "", 
       "labStartTime": "", 
       "labEndTime": "" 
      } 
     ] 
    } 
] 

я хотел бы, чтобы результат был следующим: результат должен содержать весь ассоциативный ассоциатив курса, чтобы я мог получить доступ ко всем его данным (sectionNumber, regNum, days, ..etc)

Примечание. Я не знаю, сколько курсов или разделов будет. Кроме того, курс никогда не должен сравниваться с самим собой.

желаемый результат:

[ 
    [ [CIS 01 Array],[MATH 01 Array] ], 
    [ [CIS 01 Array],[MATH 02 Array] ], 
    [ [CIS 02 Array],[MATH 01 Array] ], 
    [ [CIS 02 Array],[MATH 02 Array]] 
] 

Каждый массив результат должен содержать массивы (которые имеют одинаковую длину, как количество курсов) массивы.


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

for($i = 0; $i < count($json_data); $i++){ //courses 
    for($k = 0; $k < count($json_data[$i]["sections"]); $k++){ //first sections 
     for($p = 1; $p < count($json_data[$i]["sections"]); $p++){ //all other courses but 1 
      for($h = 0; $h < count($json_data[$i]["sections"][$p]); $h++){ 
       echo $json_data[$i]["sections"][$k]["labDay"]; 
      } 
     } 
    } 
} 
+0

В зависимости от ограничений памяти вы можете использовать рекурсивную функцию, которая добавляет все оставшиеся элементы, включая себя в массив результатов. –

+0

@ChrisThorsvik Но должен быть массив результатов, содержащий массивы, содержащие массивы. Кроме того, курс никогда не должен сравниваться с самим собой. –

+0

Можете ли вы прояснить одно? Вы сказали: «Каждый массив результатов должен содержать массивы ..., которые имеют ту же длину, что и количество курсов». Вы имели в виду, что каждый элемент массива результатов должен содержать ровно один курс из каждого отдела? –

ответ

0

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

function crossProduct() { 
    $_ = func_get_args(); 
    if (count($_) == 0) { 
     return array(array()); 
    }     
    $a = array_shift($_);   
    $c = call_user_func_array('crossProduct', $_);   
    $r = array(); 
    foreach ($a as $v) { 
     foreach ($c as $p) { 
      $r[] = array_merge(array($v), $p); 
     } 
    } 
    return $r; 
} 

Вам однако нужно предварительно обработать ваше решение немного :

$allDepartmentsSections = []; 
foreach ($jsonArrayEntry as $entry) { 
     $sections = []; 
     foreach ($entry["section"] as $section) { 
       $sections[] = $section + [ "department" => $entry["department"], "name"=>$entry["name"] ]; 
     } 
     $allDepartmentsSections[] = $sections; 
} 

Вы можете сделать:

call_user_func_array('crossProduct', $allDepartmentsSections); 

Посмотри работать в https://eval.in/725763

+0

Точно, что мне нужно. Огромное спасибо! –

0

Вот мое решение:

//simplified json for answer, you could use yours 
$json = '[ 
    { 
     "department": "CIS", 
     "sections": [ 
      { 
       "sectionNumber": "CIS-1" 
      }, 
      { 
       "sectionNumber": "CIS-2" 
      } 
     ] 
    },{ 
     "department": "ENG", 
     "sections": [ 
      { 
       "sectionNumber": "ENG-1" 
      }, 
      { 
       "sectionNumber": "ENG-2" 
      } 
     ] 
    }, 
    { 
     "department": "MATH", 
     "sections": [ 
      { 
       "sectionNumber": "MATH-1" 
      }, 
      { 
       "sectionNumber": "MATH-2" 
      } 
     ] 
    } 
]'; 

$data = json_decode($json, true); 
$cartesian = []; 

//Use array map to run over all array items 
array_map(function($item) use($data, &$cartesian) { 
    //starting from your element, search for all others "next departments" 
    for($i = array_search($item, $data)+1, $c = count($data); $i<$c; $i++) { 
     //foreach "next departments" get section 
     foreach($data[$i]['sections'] as $section) { 
      //foreach sections of current department, do 
      foreach($item['sections'] as $item_section) { 
       //append to cartesian resultset 
       $cartesian[] = [$item_section, $section]; 
      } 
     } 
    } 
}, $data); 

//create a reverse array, to get all reverse combinations. 
// Ex.: We have CIS-1 -> MATH-1, now we have MATH-1 -> CIS-1 
$reverse = array_map('array_reverse', $cartesian); 
//merge to cartesian resultset 
$cartesian = array_merge($cartesian, $reverse); 

print_r(count($cartesian)); print_r($cartesian); 

Выход:

24 

    Array 
(
    [0] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

     ) 

    [1] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

     ) 

    [2] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

     ) 

    [3] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

     ) 

    [4] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

     ) 

    [5] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

     ) 

    [6] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

     ) 

    [7] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

     ) 

    [8] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

     ) 

    [9] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

     ) 

    [10] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

     ) 

    [11] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

     ) 

    [12] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

     ) 

    [13] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

     ) 

    [14] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

     ) 

    [15] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

     ) 

    [16] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

     ) 

    [17] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

     ) 

    [18] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-1 
       ) 

     ) 

    [19] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => CIS-2 
       ) 

     ) 

    [20] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

     ) 

    [21] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-1 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

     ) 

    [22] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-1 
       ) 

     ) 

    [23] => Array 
     (
      [0] => Array 
       (
        [sectionNumber] => MATH-2 
       ) 

      [1] => Array 
       (
        [sectionNumber] => ENG-2 
       ) 

     ) 

) 
+0

Спасибо за решение –