使用Cartesian Product PHP获取所有独特的数组组合

时间:2017-01-27 16:34:15

标签: php cartesian-product

我正在尝试为未知数量的数组获得所有可能的组合:

这是JSON数据结构

[
    {
        "department": "CIS",
        "name": "Intro to CIS",
        "sections": [
            {
                "sectionNumber": "01",
                "regNum": "012345",
                "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": "012345",
                "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) < / p>

  

注意,我不知道会有多少课程或部分。此外,一门课程永远不应该与自己比较。

所需结果:

[
    [ [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"];
            }
        }
    }
}

3 个答案:

答案 0 :(得分:0)

答案 1 :(得分: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
                )

        )

)

答案 2 :(得分: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

工作
相关问题