webentwicklung-frage-antwort-db.com.de

Wie kann man ein mehrdimensionales Array auf ein einfaches in PHP "reduzieren"?

Es ist wahrscheinlich eine Anfängerfrage, aber ich gehe schon länger durch die Dokumentation und kann keine Lösung finden. Ich dachte, ich könnte implode für jede Dimension verwenden und dann diese Zeichenfolgen mit str_split wieder zusammenfügen, um ein neues einfaches Array zu erstellen. Ich weiß jedoch nie, ob das Join-Muster nicht auch in Werten enthalten ist. Nach str_split könnten meine ursprünglichen Werte brechen.

Gibt es so etwas wie combine($array1, $array2) für Arrays innerhalb eines mehrdimensionalen Arrays?

68
Adriana

Verwenden Sie 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)
}
*/

?>

Getestet mit PHP 5.5.9-1ubuntu4.24 (cli) (gebaut: 16. März 2018 12:32:06)

41
Luc M
$array  = your array

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

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

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

Hier ist eine andere Lösung (arbeitet mit mehrdimensionalem Array):

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);
115
Prasanth Bendra

Dies ist eine einzeilige, SUPER einfach zu bedienen:

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

Es ist sehr leicht zu verstehen, innerhalb der anonymen Funktion/Schließung. $v ist der Wert Ihres $original_array.

44
Arnold Roa
// $array = your multidimensional array

$flat_array = array();

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

$flat_array[$k] = $v;

}

Ebenfalls dokumentiert: http://www.phpro.org/examples/Flatten-Array.html

19
upallnite
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;
}
5
chaos

Eine andere Methode aus PHP Benutzerkommentaren (vereinfacht) und hier :

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;
}

Der große Vorteil dieser Methode besteht darin, dass sie die Tiefe der Rekursion nachverfolgt, falls Sie diese während des Abflachens benötigen.
Dies wird ausgegeben:

$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
SamGoody

Mit PHP 7 können Sie Generatoren und Generatordelegierung (yield from) verwenden, um ein Array zu reduzieren:

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);
}

Beispiel:

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

var_dump(array_flatten($array));

http://3v4l.org/RU30W

4
kelunik

In PHP> = 5.3 können Sie, basierend auf der Antwort von Luc M (der ersten), solche Verschlüsse verwenden

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

Ich liebe das, weil ich den Code der Funktion nicht mit Anführungszeichen umgeben muss, wie bei der Verwendung von create_function ().

4
hisa_py

Eine nicht rekursive Lösung (aber zerstörerisch):

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
phihag

Wenn Sie ein Array von Arrays haben, das nicht weiter als eine Ebene tief ist (ein Anwendungsfall, den ich häufig finde), können Sie mit array_merge und dem Splat-Operator davonkommen.

<?php

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

Ausgabe:

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

Der Splat-Operator ändert effektiv das Array von Arrays in eine Liste von Arrays als Argumente für array_merge.

2
Josh Johnson

Verwenden von Funktionen höherer Ordnung (Hinweis: Ich verwende inline anonyme Funktionen , die in PHP 5.3 erschienen sind): 

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()
    );
}
2
Paul d'Aoust

Wenn Sie mit dem Verlust von Array-Schlüsseln einverstanden sind, können Sie ein mehrdimensionales Array mit einem rekursiven Abschluss als Rückruf verkleinern, der array_values ​​() verwendet. Stellen Sie dabei sicher, dass dieser Callback ein Parameter für array_walk () ist.

<?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);

Der Nachteil des vorherigen Beispiels besteht darin, dass weit mehr Code geschrieben wird als mit der folgenden Lösung, die array_walk_recursive () zusammen mit einem vereinfachten Rückruf verwendet:

<?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);

Siehe live code

Dieses Beispiel scheint dem vorherigen vorzuziehen, da die Details darüber, wie Werte aus einem mehrdimensionalen Array extrahiert werden, ausgeblendet werden. Sicherlich kommt es zu einer Iteration, aber ob Rekursions- oder Kontrollstrukturen erforderlich sind, wissen Sie nur aus array.c. Da sich die funktionale Programmierung eher auf Input und Output als auf die Minutien des Erzielens eines Ergebnisses konzentriert, kann man sich sicherlich nicht darüber im Klaren sein, wie die Iteration hinter den Kulissen stattfindet, das heißt, bis ein Arbeitgeber eine solche Frage stellt. 

1
slevy1
/*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;
}
1
Iman

Ein neuer Ansatz, der auf der vorherigen durch Chaos übergebenen Beispielfunktion basiert und den Fehler des Überschreibens von String-Schlüsseln in Multiarrays behebt:

# 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
xtrm

sie können dies versuchen:

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
TomSawyer

Ich habe einen einfachen Weg gefunden, ein mehrstufiges Array in eins zu konvertieren. Ich benutze die Funktion "http_build_query", die das Array in eine URL-Zeichenfolge konvertiert. Dann teilen Sie die Zeichenfolge mit explodieren auf und dekodieren den Wert.

Hier ist ein Beispiel.

$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;

Einfacher Ansatz ..Siehe es über Rekursion ..

<?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
Paras Agarwal

Sie können die flatten - Funktion aus der Nicht-Standard-Bibliothek PHP (NSPL) verwenden. Es funktioniert mit Arrays und beliebigen iterierbaren Datenstrukturen.

assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]]));
0