合并数组数组而不会丢失值

时间:2013-12-21 16:22:02

标签: php arrays sorting multidimensional-array

Array
(
    [0] => Array
        (
            [color] => Brown
        )

    [1] => Array
        (
            [color] => Green
        )

    [2] => Array
        (
            [width] => 34
        )

)

我需要像这样做

[color] => Array
    (
        [0] => green
        [1] => brown
    )

[width] => Array
    (
        [0] => 34
    )

我正在尝试使用所有数组工具。但我不能像我想要的那样。

6 个答案:

答案 0 :(得分:7)

这对array_column()非常简单(需要PHP> = 5.5.0):

$result = array[
  'color' => array_column($arr, 'color'),
  'width' => array_column($arr, 'width')
];

活小提琴:https://eval.in/81746

<小时/> 如果您事先不知道密钥,则使用array_walk_recursive()

是另一种解决方案
$result = [];
array_walk_recursive($arr, function($value, $key) use (&$result) {
  if (!isset($result[$key])) {
    $result[$key] = [];
  }
  $result[$key][] = $value;
});

活小提琴:https://eval.in/81745

答案 1 :(得分:4)

所以你想合并数组递归 ...如果只有such an array_merge_recursive函数存在...你为什么不试试这个:

$a = array(
    array('colour' => 'green'),
    array('colour' => 'blue'),
    array('width' => 123)
);
$result = array();
foreach($a as $arr)
{
    $result = array_merge_recursive($result, $arr);
}
var_dump($result);

这对我来说非常好,as you can see for yourself here, too

是的,在给定的示例中,width将不是数组,因此您得到:

array('colour' => array('green','blue'),'width' => 123);

如果你需要一切都是一个数组,那么一个脏修复就是使用一个强制转换:

foreach($result as $k => $v) $result[$k] = (array) $v;

第二次重新分配$result值,只将它们作为数组转换,确保所有值显然都是数组。强制转换为数组的数组将保持不变,就像(int) 1仍然计算为1.原始值(字符串,整数,双精度,...)将包装 int数组,但是一个对象将被转换为数组,所以要小心。如果对象可能出现在此数组中:

foreach($result as $k => $v) $result[$k] = is_array($v) ? $v : array($v);

可能是更安全的赌注。但是,我选择了 not 来实现这种方法,因为我仍然发现将所有内容包装成一个只包含1个值的数组非常繁琐而愚蠢......

对于那些偏爱不可维护代码的人,以下单行是精简的,但是通知免费&amp;相同代码的工作示例:

foreach($a as $arr) $result = array_merge_recursive(isset($result) ? $result : array(), $arr);

这是对斯图尔特韦克菲尔德的反应,他建议使用call_user_func_array进行单线程,这是我一直反对的,只要我活着和呼吸,BTW ......

答案 2 :(得分:1)

我想这应该这样做,特别是如果你不知道你将拥有什么键:

foreach ($original_array as $val1)
    foreach ($val1 as $key2=>$val2)
        $merged_array[$key2][] = $val2;

答案 3 :(得分:0)

只需使用下面的foreach - arrayName =原始数组 -

foreach($arrayName as $newArr){
 if($newArr['color']){
   $tempArr['color'][] = $newArr['color'];
  }
 if($newArr['width']){
  $tempArr['width'][] = $newArr['width'];
 }
}

答案 4 :(得分:0)

答案 5 :(得分:0)

在Elias的array_merge_recursive回答的基础上,下面介绍了一个小修补程序,将单项合并转换为数组:

/* This version uses the function array_merge_recursive to collect
 * all of the values for the nested arrays by key
 *
 * @see http://willem.stuursma.name/2011/09/08/parallel-array_map-with-hiphop/
 * @see http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/ 
 * for why for loops are better than array_map in general
 */
$result = array_map(function($item) {

    /* The array_merge_recursive function doesn't add
     * values to an array if there was only one found
     * if the item isn't an array, make it an array
     */
    return is_array($item) ? $item : array($item);

/* Calls the array_merge_recursive function applying all of
 * the nested arrays as parameters.
 *
 * @see http://php.net/array_merge_recursive
 * @see http://www.php.net/call_user_func_array
 */
}, call_user_func_array('array_merge_recursive', $arr));

产地:

Array 
    (
        [color] => Array
            (
                [0] => green
                [1] => brown
            )

        [width] => Array
            (
                [0] => 34
            )
    )

而不是:

Array 
    (
        [color] => Array
            (
                [0] => green
                [1] => brown
            )

        [width] => 34
    )

或者,是ComFreek的array_column解决方案的动态方法。

这为您提供了键的数组:

/* Gets the keys of the nested arrays as a single array of keys by first
 * mapping the nested arrays to an array of keys they contain and then
 * by merging these arrays and killing duplicates
 *
 * @see http://php.net/function.array-unique
 * @see http://www.php.net/call_user_func_array
 * @see http://www.php.net/array_merge
 * @see http://www.php.net/array_map
 */
$keys = array_unique(call_user_func_array('array_merge', array_map(function($item) {

    /* Replaces the nested array of keys and values with an array
     * of keys only in the mapped array
     *
     * @see http://www.php.net/array_keys
     */
    return array_keys($item);
}, $arr)));

如:

Array
    (
        [0] => color
        [1] => width
    )

可以与此代码段一起使用:

/* Combines the array of keys with the values from the nested
 * arrays.
 *
 * @see http://php.net/array_combine
 * @see http://www.php.net/manual/en/function.array-map.php
 */
$result = array_combine($keys, array_map(function($key) use($arr) {

    /* Collects the values from the nested arrays
     *
     * @see http://php.net/array_column
     */
    return array_column($arr, $key);
}, $keys));

创建所需的输出:

Array 
    (
        [color] => Array
            (
                [0] => green
                [1] => brown
            )

        [width] => Array
            (
                [0] => 34
            )
    )

注意:功能调用在大多数语言中都可以通过命令式样式获益,尽管它确实需要在心理上进行转换。功能模式开辟了低级优化的可能性,否则将无法实现。例如,数组映射可以并行执行,而for循环则不能,for循环将始终具有必须按顺序执行的限制。