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

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

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

Ответы [ 21 ]

2 голосов
/ 10 мая 2016

Использование функций высшего порядка (примечание: я использую встроенные анонимные функции , появившиеся в PHP 5.3):

function array_flatten($array) {
    return array_reduce(
        $array,
        function($prev, $element) {
            if (!is_array($element))
                $prev[] = $element;
            else
                $prev = array_merge($prev, array_flatten($element));
            return $prev;
        },
        array()
    );
}
1 голос
/ 11 апреля 2011

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

<?php  

$array = [1,2,3,[5,6,7]];
$nu_array = null;
$callback = function ( $item ) use(&$callback, &$nu_array) {
    if (!is_array($item)) {
    $nu_array[] = $item;
    }
    else
    if ( is_array( $item ) ) {
     foreach( array_values($item) as $v) {
         if ( !(is_array($v))) {
             $nu_array[] = $v;
         }
         else
         { 
             $callback( $v );
         continue;
         }    
     }
    }
};

array_walk($array, $callback);
print_r($nu_array);

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

<?php  

$array = [1,2,3,[5,6,7]];

$nu_array = [];
array_walk_recursive($array, function ( $item ) use(&$nu_array )
                     {
                         $nu_array[] = $item;
                     }
);
print_r($nu_array);

См. живой код

Этот пример кажется предпочтительнее предыдущего, скрывая детали того, как значения извлекаются из многомерного массива. Конечно, итерация происходит, но влечет ли она за собой рекурсию или управляющую структуру (структуры), вы узнаете только из прочтения array.c . Поскольку функциональное программирование фокусируется на вводе и выводе, а не на мелочах получения результата, несомненно, можно не беспокоиться о том, как происходит закулисная итерация, то есть до тех пор, пока перспективный работодатель не задаст такой вопрос.

1 голос
/ 31 августа 2011

Новый подход, основанный на функции предыдущего примера, представленной хаосом, которая исправляет ошибку перезаписи строковых ключей в мульти-массивах:

# 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

function flatten_array($array, $preserve_keys = 2, &$out = array(), &$last_subarray_found) 
{
        foreach($array as $key => $child)
        {
            if(is_array($child))
            {
                $last_subarray_found = $key;
                $out = flatten_array($child, $preserve_keys, $out, $last_subarray_found);
            }
            elseif($preserve_keys + is_string($key) > 1)
            {
                if ($last_subarray_found)
                {
                    $sfinal_key_value = $last_subarray_found . "_" . $key;
                }
                else
                {
                    $sfinal_key_value = $key;
                }
                $out[$sfinal_key_value] = $child;
            }
            else
            {
                $out[] = $child;
            }
        }

        return $out;
}

Example:
$newarraytest = array();
$last_subarray_found = "";
$this->flatten_array($array, 2, $newarraytest, $last_subarray_found);
1 голос
/ 21 февраля 2012

Вы можете попробовать это:

function flat_an_array($a)
{
    foreach($a as $i)
    {
        if(is_array($i)) 
        {
            if($na) $na = array_merge($na,flat_an_array($i));
            else $na = flat_an_array($i);
        }
        else $na[] = $i;
    }
    return $na;
}
1 голос
/ 11 сентября 2011
/*consider $mArray as multidimensional array and $sArray as single dimensional array
this code will ignore the parent array
*/

function flatten_array2($mArray) {
    $sArray = array();

    foreach ($mArray as $row) {
        if ( !(is_array($row)) ) {
            if($sArray[] = $row){
            }
        } else {
            $sArray = array_merge($sArray,flatten_array2($row));
        }
    }
    return $sArray;
}
0 голосов
/ 11 января 2019

Я нашел простой способ конвертировать многоуровневый массив в один. Я использую функцию "http_build_query", которая преобразует массив в строку URL. Затем разделите строку с помощью разнесения и декодируйте значение.

Вот пример.

$converted = http_build_query($data);
$rows = explode('&', $converted);
$output = array();
foreach($rows AS $k => $v){
   list($kk, $vv) = explode('=', $v);
   $output[ urldecode($kk) ] =  urldecode($vv);
}
return $output;
0 голосов
/ 11 декабря 2016

Простой подход .. Посмотрите через рекурсию ..

<?php

function flatten_array($simple){
static $outputs=array();
foreach ( $simple as $value)
{
if(is_array($value)){
    flatten_array($value);
}
else{
    $outputs[]=$value;
}

}
return $outputs;
}

$eg=['s'=>['p','n'=>['t']]];
$out=flatten_array($eg);
print_r($out);

?>
0 голосов
/ 21 мая 2016

Можно использовать функцию flatten из Нестандартная библиотека PHP (NSPL) . Работает с массивами и любыми повторяемыми структурами данных.

assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]]));
0 голосов
/ 12 ноября 2015

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

function _flatten_array($arr) {
  while ($arr) {
    list($key, $value) = each($arr); 
    is_array($value) ? $arr = $value : $out[$key] = $value;
    unset($arr[$key]);
  }
  return (array)$out;
}
0 голосов
/ 25 сентября 2015

все это не работает для меня ... так что пришлось самому запускать. работает просто отлично:

<code>function arrayFlat($arr){
$out = '';
    foreach($arr as $key => $value){

        if(!is_array($value)){
            $out .= $value.',';
        }else{
            $out .= $key.',';
            $out .= arrayFlat($value);
        }

    }
    return trim($out,',');
}


$result = explode(',',arrayFlat($yourArray));
echo '<pre>';
print_r($result);
echo '
';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...