亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

用PHP關聯數組求笛卡兒積

用PHP關聯數組求笛卡兒積

拉丁的傳說 2019-06-24 09:28:20
假設我有一個數組,如下所示:Array(     [arm] => Array         (             [0] => A            [1] => B            [2] => C        )     [gender] => Array         (             [0] => Female             [1] => Male         )     [location] => Array         (             [0] => Vancouver             [1] => Calgary         ))如何在保留外部關聯數組的鍵并在內部數組中使用它們的同時,找到笛卡兒積?算法的結果應該是:Array(     [0] => Array         (             [arm] => A            [gender] => Female             [location] => Vancouver         )     [1] => Array         (             [arm] => A            [gender] => Female             [location] => Calgary         )     [2] => Array         (             [arm] => A            [gender] => Male             [location] => Vancouver         )...etc.我已經查閱了很多笛卡爾積算法,但我仍然停留在如何保存關聯鍵的細節上。我目前使用的算法只給出數字索引:    $result = array();     foreach ($map as $a) {         if (empty($result)) {             $result = $a;             continue;         }         $res = array();         foreach ($result as $r) {             foreach ($a as $v) {                 $res[] = array_merge((array)$r, (array)$v);             }         }         $result = $res;     }     print_r($result);任何幫助都將不勝感激。用PHP關聯數組求笛卡兒積
查看完整描述

3 回答

?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

我能想到的是:

function inject($elem, $array) {
    return array_map(function ($n) use ($elem) { return array_merge((array)$elem, (array)$n); }, $array);}function zip($array1, $array2) {
    return array_reduce($array1, function ($v, $n) use ($array2) { return array_merge($v, inject($n, $array2));  }, array());}
    function cartesian_product($array) {
    $keys = array_keys($array);
    $prod = array_shift($array);
    $prod = array_reduce($array, 'zip', $prod);
    return array_map(function ($n) use ($keys) { return array_combine($keys, $n); }, $prod);}

(下面使用偽數組/列表/字典表示法,因為PHP對于這類事情太冗長了。)

這個inject函數變換a, [b][(a,b)],即它向數組的每個值注入一個值,返回一個數組。不管是不是ab已經是一個數組了,它將始終返回一個二維數組。

inject('a', ['foo', 'bar'])
    =>  [('a', 'foo'), ('b', 'bar')]

這個zip函數應用inject函數到數組中的每個元素。

zip(['a', 'b'], ['foo', 'bar'])
    =>  [('a', 'foo'), ('a', 'bar'), ('b', 'foo'), ('b', 'bar')]

請注意,這實際上產生了笛卡爾積,因此zip有點用詞不當。簡單地將此函數應用于數據集中的所有元素,就可以得到任意長度數組的笛卡兒積。

zip(zip(['a', 'b'], ['foo', 'bar']), ['42', '76'])
    =>  [('a', 'foo', '42'), ('a', 'foo', '76'), ('a', 'bar', '42'), …]

這不包含鍵,但是由于元素在結果集中都是按順序排列的,所以您可以簡單地將鍵重新注入結果。

array_combine(['key1', 'key2', 'key3'], ['a', 'foo', '42'])
    =>  [ key1 : 'a', key2 : 'foo', key3 : '42' ]

將其應用于產品中的所有元素,將得到所需的結果。

如果您愿意,可以將上述三個函數折疊成一個長語句(這也可以清除錯誤的名稱)。


對于PHP<=5.2沒有匿名函數的“展開”版本如下所示:

function inject($elem, $array) {
    $elem = (array)$elem;
    foreach ($array as &$a) {
        $a = array_merge($elem, (array)$a);
    }
    return $array;}function zip($array1, $array2) {
    $prod = array();
    foreach ($array1 as $a) {
        $prod = array_merge($prod, inject($a, $array2));
    }
    return $prod;}function cartesian_product($array) {
    $keys = array_keys($array);
    $prod = array_shift($array);
    $prod = array_reduce($array, 'zip', $prod);

    foreach ($prod as &$a) {
        $a = array_combine($keys, $a);
    }
    return $prod;}


查看完整回答
反對 回復 2019-06-24
  • 3 回答
  • 0 關注
  • 625 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號