Php 多维数组中具有公共元素的子数组合并

Php 多维数组中具有公共元素的子数组合并,php,multidimensional-array,compare,Php,Multidimensional Array,Compare,我正在开发一个由PHP支持的游戏。我有一个系统,可以随机生成带有路径的地图。以下是一个例子: (我更新了此帖子,但没有足够的代表将此图像直接发布到其他人使用其代表所做的页面,抱歉) 地图的每个单元格都有一个4位数的字符串,表示行程(W、N、E、S)。因此,上面地图中的单元格11将有一个字符串1110,单元格17将有一个字符串1001。这个字符串(又名NavString)是在规则中随机生成的,以防止它将玩家从地图上赶走 任何只有一个移动方向的单元格都放入$endcaps(数组)。此外,任何具有3

我正在开发一个由PHP支持的游戏。我有一个系统,可以随机生成带有路径的地图。以下是一个例子:

(我更新了此帖子,但没有足够的代表将此图像直接发布到其他人使用其代表所做的页面,抱歉)

地图的每个单元格都有一个4位数的字符串,表示行程(W、N、E、S)。因此,上面地图中的单元格11将有一个字符串1110,单元格17将有一个字符串1001。这个字符串(又名NavString)是在规则中随机生成的,以防止它将玩家从地图上赶走

任何只有一个移动方向的单元格都放入$endcaps(数组)。此外,任何具有3个和4个移动方向的单元格都会放入$endcaps,但在$endcaps中包含的实体数与移动方向的实体数相同(等式,一个3向交叉点会将3个条目放入$endcaps)。没有添加只有2个方向的单元格,这是因为它们有1个方向输入,只有1个不同的方向输出,所以这是一条直线路径输入和输出;没有分支,也没有死胡同

我通过$endcaps对每个循环进行foreach循环,以获得要记录的路径的每个部分的起点。使用NavString,我跟踪从$endcaps收集的单元格的每条路径,直到到达$endcaps中的另一个单元格(使用in_数组($endcaps)),整个过程都记录了通过$path[$path][$step]的单元格编号。每个新的$endcap I$path++和$endcaps I$step++之间的每个新单元格

下面是$PATH在退出循环后的外观示例: [注意:图像中的贴图是此2D阵列的来源]

Array
(
[0] => Array
    (
        [0] => 4
        [1] => 9
        [2] => 14
    )

[1] => Array
    (
        [0] => 6
        [1] => 5
        [2] => 10
        [3] => 11
    )

[2] => Array
    (
        [0] => 6
        [1] => 1
        [2] => 2
        [3] => 7
    )

[3] => Array
    (
        [0] => 6
        [1] => 7
    )

[4] => Array
    (
        [0] => 6
        [1] => 11
    )

[5] => Array
    (
        [0] => 7
        [1] => 6
    )

[6] => Array
    (
        [0] => 7
        [1] => 2
        [2] => 1
        [3] => 6
    )

[7] => Array
    (
        [0] => 7
        [1] => 12
        [2] => 11
    )

[8] => Array
    (
        [0] => 8
        [1] => 13
    )

[9] => Array
    (
        [0] => 11
        [1] => 10
        [2] => 5
        [3] => 6
    )

[10] => Array
    (
        [0] => 11
        [1] => 6
    )

[11] => Array
    (
        [0] => 11
        [1] => 12
        [2] => 7
    )

[12] => Array
    (
        [0] => 13
        [1] => 8
    )

[13] => Array
    (
        [0] => 13
        [1] => 14
    )

[14] => Array
    (
        [0] => 13
        [1] => 18
        [2] => 19
        [3] => 14
    )

[15] => Array
    (
        [0] => 14
        [1] => 13
    )

[16] => Array
    (
        [0] => 14
        [1] => 9
        [2] => 4
    )

[17] => Array
    (
        [0] => 14
        [1] => 19
        [2] => 18
        [3] => 13
    )

[18] => Array
    (
        [0] => 16
        [1] => 17
        [2] => 22
        [3] => 23
    )

[19] => Array
    (
        [0] => 23
        [1] => 22
        [2] => 17
        [3] => 16
    )

)
我想将子数组中的like值与$path中的其他子数组进行比较。如果有1+个匹配项,则我希望将两个数组合并在一起,并继续查找至少具有1个公共值的子数组,但我需要允许在比较中添加任何新的添加项

因此,理想情况下,这应该合并到一个2D阵列,在所有这些都说了算之后,该阵列只有3个子阵列。上述示例的预期结果应如下所示:

array (
    array(1,2,5,6,7,10,11,12)
    array(4,9,14,8,13,18,19)
    array(16,17,22,23)
)
$array = array(
    array(6,5,0,1,6),
    array(6,11),
    array(11,10,15,16,17,12),
    array(11,12),
    array(12,13),
    array(18,19,14),
    array(7,8,3,4)
);
$array = array(
    array(0,1,5,6,11,10,15,16,17,12,13),
    array(18,19,14),
    array(7,8,3,4)
);
以上将是一个完美的代表途径,我可以用它来确保入口和出口是连接的,玩家不会被困

因此,我的问题是如何将$path(在第一个代码块中)细化到第二个代码块中的数组?记住,这些映射是随机生成的,$PATH可以有任意数量的子数组,子数组可以有任意数量的元素,可以是任意的单元号(取决于系统生成路径的方式)

我希望这足够详细,你们可以帮助我,上次我问怎么做,他们说我太含糊了(经过深思熟虑,我同意)。如果这还不够,那么


更新到目前为止我尝试的内容

$set=0;
foreach($paths as $loop1key=>$loop1) {
  foreach($paths as $loop2key=>$loop2) {
    if(count(array_intersect($loop1,$loop2)) > 0) {
      $consolidated = array_merge($loop1,$loop2);
      unset($paths[$loop2key],$paths[$loop1key]);
      $loop1 = $consolidated;
    }
  }
  $after[$set]=$consolidated;
  $set++;
}
和(由@hackerartist提出):

进入如下数组:

array (
    array(1,2,5,6,7,10,11,12)
    array(4,9,14,8,13,18,19)
    array(16,17,22,23)
)
$array = array(
    array(6,5,0,1,6),
    array(6,11),
    array(11,10,15,16,17,12),
    array(11,12),
    array(12,13),
    array(18,19,14),
    array(7,8,3,4)
);
$array = array(
    array(0,1,5,6,11,10,15,16,17,12,13),
    array(18,19,14),
    array(7,8,3,4)
);
下面是我用来尝试实现这一点的代码: $path将是上面的$array

for($x=0;$x<count($paths);$x++){//Loop through paths
                $paths = array_values($paths);//Reset keys
                for($y=0;$y<count($paths);$y++){//Loop through again
                    if($x != $y){//If we arent on the same array
                        if(count(array_intersect($paths[$x],$paths[$y]))){//If there is even 1 matching element
                            $paths[$x] = array_unique(array_merge($paths[$x],$paths[$y]));//Merge arrays
                            unset($paths[$y]);//Remove array just merged
                        }
                    }

                }
            }

对于($x=0;$x它可能不是最优雅的解决方案,但它在100%的时间内都能正常工作。很简单,我将对优化代码运行两次,使用第一次到第二次的输出,然后在第二次从函数返回。重新调用嵌入函数本身(所以我猜这意味着它是一个递归函数,对吗?)无论如何,这里有一个数组的示例,它不会一路细化(它错过了合并):

一旦运行它,就会产生以下结果:

$array = Array(
    [0] => Array(
            [0] => 21,
            [1] => 22,
            [2] => 17,
            [4] => 18,
            [5] => 23,
            [6] => 12,
            [7] => 11,
            [8] => 10,
            [9] => 1,
            [10] => 0,
            [11] => 5,
            [12] => 6),

    [1] => Array(
            [0] => 7,
            [1] => 12,
            [2] => 2,
            [3] => 3,
            [4] => 4,
            [5] => 9,
            [6] => 8),

    [2] => Array(
            [0] => 15,
            [1] => 16));
这并不完全正确,因为$array[0][6]和$array[1][1]都是12,它们所在的数组应该组合在一起,但它们没有。我不确定它为什么没有得到它,但我认为一个简单的解决方案是再次运行它,这样就可以了。下面是完整的函数:

function linkSegments($paths=array(),$ranthru=1){
               if(is_empty($paths)){
                 echo "No segments to link!";die;
               } else {
            for($x=0;$x<count($paths);$x++){//Loop through paths
                $paths = array_values($paths);//Reset keys
                for($y=0;$y<count($paths);$y++){//Loop through again
                    if($x != $y){//If we arent on the same array
                        if(count(array_intersect($paths[$x],$paths[$y]))){//If there is even 1 matching element
                            $paths[$x] = array_unique(array_merge($paths[$x],$paths[$y]));//Merge arrays
                            unset($paths[$y]);//Remove array just merged
                        }
                    }

                }
            }
            if($ranthru == 1){
                $paths = linkSegments($paths,$ranthru=2);
                return $paths;//Set path data to class
            } else {
                return $paths;
            }
               }
        }

如果你知道一种更有效的方法,请告诉我!这是为了一个游戏,所以我能越快做到越好:D

我能问一下你到目前为止都做了些什么吗?呵呵,你介意我用它更新你原来的帖子吗?它会更具可读性。
function linkSegments($paths=array(),$ranthru=1){
               if(is_empty($paths)){
                 echo "No segments to link!";die;
               } else {
            for($x=0;$x<count($paths);$x++){//Loop through paths
                $paths = array_values($paths);//Reset keys
                for($y=0;$y<count($paths);$y++){//Loop through again
                    if($x != $y){//If we arent on the same array
                        if(count(array_intersect($paths[$x],$paths[$y]))){//If there is even 1 matching element
                            $paths[$x] = array_unique(array_merge($paths[$x],$paths[$y]));//Merge arrays
                            unset($paths[$y]);//Remove array just merged
                        }
                    }

                }
            }
            if($ranthru == 1){
                $paths = linkSegments($paths,$ranthru=2);
                return $paths;//Set path data to class
            } else {
                return $paths;
            }
               }
        }
$array = Array(
    [0] => Array(
            [0] => 21,
            [1] => 22,
            [2] => 17,
            [4] => 18,
            [5] => 23,
            [6] => 12,
            [7] => 11,
            [8] => 10,
            [9] => 1,
            [10] => 0,
            [11] => 5,
            [12] => 6,
            [13] => 7,
            [14] => 8,
            [15] => 9,
            [16] => 2,
            [17] => 3,
            [18] => 4),

    [1] => Array(
            [0] => 15,
            [1] => 16));