Как «сгладить» многомерный массив в простой в PHP? - PullRequest
70 голосов
/ 09 февраля 2009

Вероятно, это вопрос новичка, но я уже давно изучаю документацию и не могу найти никакого решения. Я думал, что смогу использовать implode для каждого измерения, а затем соединить эти строки вместе с str_split, чтобы создать новый простой массив. Однако я никогда не знаю, не будет ли шаблон соединения также в значениях и поэтому после выполнения str_split мои исходные значения могут сломаться.

Есть ли что-то вроде combine($array1, $array2) для массивов внутри многомерного массива?

Ответы [ 21 ]

116 голосов
/ 20 февраля 2013
$array  = your array

$result = call_user_func_array('array_merge', $array);

echo "<pre>";
print_r($result);

REF: http://php.net/manual/en/function.call-user-func-array.php

Вот еще одно решение (работает с многомерным массивом):

function array_flatten($array) {

   $return = array();
   foreach ($array as $key => $value) {
       if (is_array($value)){ $return = array_merge($return, array_flatten($value));}
       else {$return[$key] = $value;}
   }
   return $return;

}

$array  = Your array

$result = array_flatten($array);

echo "<pre>";
print_r($result);
48 голосов
/ 11 апреля 2013

Это одна строка, СУПЕР прост в использовании:

$result = array();
array_walk_recursive($original_array,function($v) use (&$result){ $result[] = $v; });

Это очень легко понять, внутри анонимной функции / замыкания. $v - это значение вашего $original_array.

41 голосов
/ 09 февраля 2009

Использование array_walk_recursive

<?php

$aNonFlat = array(
    1,
    2,
    array(
        3,
        4,
        5,
        array(
            6,
            7
        ),
        8,
        9,
    ),
    10,
    11
);

$objTmp = (object) array('aFlat' => array());

array_walk_recursive($aNonFlat, create_function('&$v, $k, &$t', '$t->aFlat[] = $v;'), $objTmp);

var_dump($objTmp->aFlat);

/*
array(11) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
  [5]=>
  int(6)
  [6]=>
  int(7)
  [7]=>
  int(8)
  [8]=>
  int(9)
  [9]=>
  int(10)
  [10]=>
  int(11)
}
*/

?>

Проверено с PHP 5.5.9-1ubuntu4.24 (cli) (сборка: 16 марта 2018 12:32:06)

19 голосов
/ 01 декабря 2009
// $array = your multidimensional array

$flat_array = array();

foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v){

$flat_array[$k] = $v;

}

Также задокументировано: http://www.phpro.org/examples/Flatten-Array.html

5 голосов
/ 10 июня 2011

Другой метод из PHP комментариев пользователей (упрощенно) и здесь :

function array_flatten_recursive($array) { 
   if (!$array) return false;
   $flat = array();
   $RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
   foreach ($RII as $value) $flat[] = $value;
   return $flat;
}

Большим преимуществом этого метода является то, что он отслеживает глубину рекурсии, если вам нужно это при выравнивании.
Это выведет:

$array = array( 
    'A' => array('B' => array( 1, 2, 3)), 
    'C' => array(4, 5) 
); 
print_r(array_flatten_recursive($array)); 

#Returns: 
Array ( 
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [3] => 4 
    [4] => 5 
)
5 голосов
/ 09 февраля 2009
function flatten_array($array, $preserve_keys = 0, &$out = array()) {
    # Flatten a multidimensional array to one dimension, optionally preserving keys.
    #
    # $array - the array to flatten
    # $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
    # $out - internal use argument for recursion
    foreach($array as $key => $child)
        if(is_array($child))
            $out = flatten_array($child, $preserve_keys, $out);
        elseif($preserve_keys + is_string($key) > 1)
            $out[$key] = $child;
        else
            $out[] = $child;
    return $out;
}
4 голосов
/ 25 августа 2011

В PHP> = 5.3 и на основании ответа Люка М (первого) вы можете использовать замыкания, подобные этому

array_walk_recursive($aNonFlat, function(&$v, $k, &$t){$t->aFlat[] = $v;}, $objTmp);

Мне это нравится, потому что мне не нужно заключать код функции в кавычки, как при использовании create_function ()

4 голосов
/ 09 февраля 2009

Нерекурсивное решение (но разрушающее порядок):

function flatten($ar) {
    $toflat = array($ar);
    $res = array();

    while (($r = array_shift($toflat)) !== NULL) {
        foreach ($r as $v) {
            if (is_array($v)) {
                $toflat[] = $v;
            } else {
                $res[] = $v;
            }
        }
    }

    return $res;
}
4 голосов
/ 29 июня 2015

В PHP 7 вы можете использовать генераторы и делегирование генераторов (yield from) для выравнивания массива:

function array_flatten_iterator (array $array) {
    foreach ($array as $value) {
        if (is_array($value)) {
            yield from array_flatten_iterator($value);
        } else {
            yield $value;
        }
    }
}

function array_flatten (array $array) {
    return iterator_to_array(array_flatten_iterator($array), false);
}

Пример:

$array = [
    1,
    2,
    [
        3,
        4,
        5,
        [
            6,
            7
        ],
        8,
        9,
    ],
    10,
    11,
];    

var_dump(array_flatten($array));

http://3v4l.org/RU30W

2 голосов
/ 22 декабря 2018

Если у вас есть массив массивов, который не превышает глубину более одного уровня (пример использования, который я считаю распространенным), вы можете обойтись без array_merge и оператора splat.

<?php

$notFlat = [[1,2],[3,4]];
$flat = array_merge(...$notFlat);
var_dump($flat);

Выход:

array(4) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}

Оператор splat эффективно изменяет массив массивов на список массивов в качестве аргументов для array_merge.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...