根据顶级(共享值)合并第二级数组

Merge second level of array based on top level (shared values)

我想合并数组的顶层,这样共享同一个父级的第二级的所有值形成该父级的单个数组。

数组 1:

Array
(
    [0] => Array
        (
            [0] => C1
            [1] => C1
            [2] => C1
            [3] => AC
            [4] => AC
        )

)

数组 2:

Array
(
    [0] => Array
        (
            [0] => C1_complete
            [1] => C1_29-95
            [2] => C1_49-95
            [3] => AC_complete
            [4] => AC_29-95
        )

)

想要的结果:

Array
(
    [0] => Array
        (
            'C1' => Array (C1_complete, C1_29-95, C1_49-95),
            'AC' => Array (AC_complete, AC_29-95)
        )

)

实现此目的的简单、优雅的方法是什么?

我寻求一种可以将相同原理推广到任何两级数组结构的解决方案。

如果我只使用数组 2 和一个简单的 foreach 循环,我可以这样做:

$array2 = [['C1_complete', 
            'C1_29-95',
            'C1_49-95',
            'AC_complete',
            'AC_29-95']];

$buffer = [];

foreach ($array2[0] as $value) {
    $buffer[substr($value, 0, 2)][] = $value;
}

$result[] = $buffer;

echo '<pre>';
print_r($result);
echo '</pre>';

输出为:

Array
(
    [0] => Array
        (
            [C1] => Array
                (
                    [0] => C1_complete
                    [1] => C1_29-95
                    [2] => C1_49-95
                )

            [AC] => Array
                (
                    [0] => AC_complete
                    [1] => AC_29-95
                )

        )

)

如果该代码在一个函数中就好了:

function classify($array)
{    
    $result = [];
    foreach ($array[0] as $value) {
        $result[substr($value, 0, 2)][] = $value;
    }
    return [$result];
}    

$array2 = [['C1_complete', 
            'C1_29-95',
            'C1_49-95',
            'AC_complete',
            'AC_29-95']];

echo '<pre>';
print_r(classify($array2));
echo '</pre>';

输出保持不变。

对于您的数组,您不需要第一个循环,但如果您的数组中有多个数组。只需循环并查找以键开头的项目:

foreach($array1 as $key => $inner) {
    foreach($inner as $k) {
        $result[$key][$k] = preg_grep("/^$k/", $array2[0]);
    }
}

使用您给定的数组:

foreach($array1[0] as $k) {
    $result[0][$k] = preg_grep("/^$k/", $array2[0]);
}

好吧,在这种情况下,simpleelegant 两种方式对我来说似乎都不太可能,因为这可能是基于意见的。一个简单的 foreach 是实现这一目标的最简单有效的方法。但是,为了优雅,您可以使用 array_walk, array_fill and array_combine 来实现这一点。

<?php

$arr1 = Array(
    Array
        (
            'C1',
            'C1',
            'C1',
            'AC',
            'AC'
    )
);

$arr2 = Array(
    Array(
            'C1_complete',
            'C1_29-95',
            'C1_49-95',
            'AC_complete',
            'AC_29-95'
    )
);


$data = array_combine(array_values($arr1[0]),array_fill(0,count($arr1[0]),[]));

array_walk($arr2[0],function($value) use (&$data){
    if(isset($data[explode("_",$value)[0]])) $data[explode("_",$value)[0]][] = $value;
});

$data = [$data]; // since you want it inside another array.

print_r($data);

演示: https://3v4l.org/VhFLH7