I have an array which is multidimensional for no reason

/* This is how my array is currently */
Array
(
[0] => Array
    (
        [0] => Array
            (
                [plan] => basic
            )

        [1] => Array
            (
                [plan] => small
            )

        [2] => Array
            (
                [plan] => novice
            )

        [3] => Array
            (
                [plan] => professional
            )

        [4] => Array
            (
                [plan] => master
            )

        [5] => Array
            (
                [plan] => promo
            )

        [6] => Array
            (
                [plan] => newplan
            )

    )

 )

I want to convert this array into this form

/*Now, I want to simply it down to this*/
Array (
[0] => basic
[1] => small
[2] => novice
[3] => professional
[4] => master
[5] => promo
[6] => newplan
)

Any idea how to do this?

Solution 1

This single line would do that:

$array = array_column($array, 'plan');

The first argument is an array | The second argument is an array key.

For details, go to official documentation: https://www.php.net/manual/en/function.array-column.php.

Solution 2

Assuming this array may or may not be redundantly nested and you're unsure of how deep it goes, this should flatten it for you:

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

Solution 3

If you come across a multidimensional array that is pure data, like this one below, then you can use a single call to array_merge() to do the job via reflection:

$arrayMult = [ ['a','b'] , ['c', 'd'] ];
$arraySingle = call_user_func_array('array_merge', $arrayMult);
// $arraySingle is now = ['a','b', 'c', 'd'];

Solution 4

Just assign it to it's own first element:

$array = $array[0];

Solution 5

For this particular case, this'll do:

$array = array_map('current', $array[0]);

It's basically the exact same question is this one, look at some answers there: PHP array merge from unknown number of parameters.

Solution 6

 $singleArray = array();

    foreach ($multiDimensionalArray as $key => $value){
        $singleArray[$key] = $value['plan'];
    }

this is best way to create a array from multiDimensionalArray array.

thanks

Solution 7

none of answers helped me, in case when I had several levels of nested arrays. the solution is almost same as @AlienWebguy already did, but with tiny difference.

function nestedToSingle(array $array)
{
    $singleDimArray = [];

    foreach ($array as $item) {

        if (is_array($item)) {
            $singleDimArray = array_merge($singleDimArray, nestedToSingle($item));

        } else {
            $singleDimArray[] = $item;
        }
    }

    return $singleDimArray;
}

test example

$array = [
        'first',
        'second',
        [
            'third',
            'fourth',
        ],
        'fifth',
        [
            'sixth',
            [
                'seventh',
                'eighth',
                [
                    'ninth',
                    [
                        [
                            'tenth'
                        ]
                    ]
                ],
                'eleventh'
            ]
        ],
        'twelfth'
    ];

    $array = nestedToSingle($array);
    print_r($array);

    //output
    array:12 [
        0 => "first"
        1 => "second"
        2 => "third"
        3 => "fourth"
        4 => "fifth"
        5 => "sixth"
        6 => "seventh"
        7 => "eighth"
        8 => "ninth"
        9 => "tenth"
        10 => "eleventh"
        11 => "twelfth"
   ]

Solution 8

Problem array:

array:2 [
  0 => array:3 [
    0 => array:4 [
      "id" => 8
      "name" => "Veggie Burger"
      "image" => ""
      "Category_type" => "product"
    ]
    1 => array:4 [
      "id" => 9
      "name" => "Veggie Pitta"
      "image" => ""
      "Category_type" => "product"
    ]
    2 => array:4 [
      "id" => 10
      "name" => "Veggie Wrap"
      "image" => ""
      "Category_type" => "product"
    ]
  ]
  1 => array:2 [
    0 => array:4 [
      "id" => 18
      "name" => "Cans 330ml"
      "image" => ""
      "Category_type" => "product"
    ]
    1 => array:4 [
      "id" => 19
      "name" => "Bottles 1.5 Ltr"
      "image" => ""
      "Category_type" => "product"
    ]
  ]
]

Solution array:

array:5 [
  0 => array:4 [
    "id" => 8
    "name" => "Veggie Burger"
    "image" => ""
    "Category_type" => "product"
  ]
  1 => array:4 [
    "id" => 9
    "name" => "Veggie Pitta"
    "image" => ""
    "Category_type" => "product"
  ]
  2 => array:4 [
    "id" => 10
    "name" => "Veggie Wrap"
    "image" => ""
    "Category_type" => "product"
  ]
  3 => array:4 [
    "id" => 18
    "name" => "Cans 330ml"
    "image" => ""
    "Category_type" => "product"
  ]
  4 => array:4 [
    "id" => 19
    "name" => "Bottles 1.5 Ltr"
    "image" => ""
    "Category_type" => "product"
  ]
]

Write this code and get your solution , $subcate is your multi dimensional array.

$singleArrayForCategory = array_reduce($subcate, 'array_merge', array());

Solution 9

You can do it just using a loop.

    $singleArray = array();

    foreach ($multiDimensionalArray as $key => $value){
        $singleArray[$key] = $value['plan'];
    }

Solution 10

Your sample array has 3 levels. Because the first level has only [0], you can hardcode your access into it and avoid an extra function/construct call.

(Code Demos)

  1. array_walk_recursive() is handy and versatile, but for this task may be overkill and certainly a bit more convoluted in terms of readability.

    array_walk_recursive($array, function($leafvalue)use(&$flat){$flat[] = $leafvalue;});
    var_export($flat);
    
  2. If this was my code, I'd be using array_column() because it is direct and speaks literally about the action being performed.

    var_export(array_column($array[0], 'plan'));
    
  3. Of course a couple of `foreach() loops will perform very efficiently because language constructs generally perform more efficiently than function calls.

    foreach ($array[0] as $plans) {
        foreach ($plans as $value) {
            $flat[] = $value;
        }
    }
    var_export($flat);
    
  4. Finally, as a funky alternative (which I can't imagine actually putting to use unless I was writing code for someone whom I didn't care for) I'll offer an array_merge_recursive() call with a splat operator (...).

    var_export(array_merge_recursive(...$array[0])['plan']);
    

Solution 11

Despite that array_column will work nice here, in case you need to flatten any array no matter of it's internal structure you can use this array library to achieve it without ease:

$flattened = Arr::flatten($array);

which will produce exactly the array you want.

Solution 12

Recently I've been using AlienWebguy's array_flatten function but it gave me a problem that was very hard to find the cause of.
array_merge causes problems, and this isn't the first time that I've made problems with it either.
If you have the same array keys in one inner array that you do in another, then the later values will overwrite the previous ones in the merged array.

Here's a different version of array_flatten without using array_merge:

function array_flatten($array) { 
  if (!is_array($array)) { 
    return FALSE; 
  } 
  $result = array(); 
  foreach ($array as $key => $value) { 
    if (is_array($value)) { 
      $arrayList=array_flatten($value);
      foreach ($arrayList as $listItem) {
        $result[] = $listItem; 
      }
    } 
   else { 
    $result[$key] = $value; 
   } 
  } 
  return $result; 
} 

Solution 13

This simple code you can use

$array = array_column($array, 'value', 'key');

Solution 14

There is an error in most voted answer. Here is the correct version.

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

The difference is on the line $result[] = $value;

Original answer was $result[$key] = $value;
The $key index is incorrect after flattering any array in the cycle.

Solution 15

Following this pattern

$input = array(10, 20, array(30, 40), array('key1' => '50', 'key2'=>array(60), 70));

Call the function :

echo "<pre>";print_r(flatten_array($input, $output=null));

Function Declaration :

function flatten_array($input, $output=null) {
if($input == null) return null;
if($output == null) $output = array();
foreach($input as $value) {
    if(is_array($value)) {
        $output = flatten_array($value, $output);
    } else {
        array_push($output, $value);
    }
}
return $output;

}

Solution 16

I've written a complement to the accepted answer. In case someone, like myself need a prefixed version of the keys, this can be helpful.

Array
(
    [root] => Array
        (
            [url] => http://localhost/misc/markia
        )

)
Array
(
    [root.url] => http://localhost/misc/markia
)
<?php
function flattenOptions($array, $old = '') {
  if (!is_array($array)) {
    return FALSE;
  }
  $result = array();
  foreach ($array as $key => $value) {
    if (is_array($value)) {
      $result = array_merge($result, flattenOptions($value, $key));
    }
    else {
      $result[$old . '.' . $key] = $value;
    }
  }
  return $result;
}

Solution 17

I had come across the same requirement to flatter multidimensional array into single dimensional array than search value using text in key. here is my code

$data = '{
    "json_data": [{
            "downtime": true,
            "pfix": {
                "max": 100,
                "threshold": 880
            },
            "ints": {
                "int": [{
                    "rle": "pri",
                    "device": "laptop",
                    "int": "Ether3",
                    "ip": "127.0.0.3"
                }],
                "eth": {
                    "lan": 57
                }
            }
        },
        {
            "downtime": false,
            "lsi": "987654",
            "pfix": {
                "min": 10000,
                "threshold": 890
            },
            "mana": {
                "mode": "NONE"
            },
            "ints": {
                "int": [{
                    "rle": "sre",
                    "device": "desk",
                    "int": "Ten",
                    "ip": "1.1.1.1",
                    "UF": true
                }],
                "ethernet": {
                    "lan": 2
                }
            }
        }
    ]
}
';

$data = json_decode($data,true);


$stack = &$data;
$separator = '.';
$toc = array();

while ($stack) {
    list($key, $value) = each($stack);
    unset($stack[$key]);
    if (is_array($value)) {
        $build = array($key => ''); # numbering without a title.
        foreach ($value as $subKey => $node)
            $build[$key . $separator . $subKey] = $node;
        $stack = $build + $stack;
        continue;
    }
    if(!is_numeric($key)){
        $toc[$key] = $value;
    }
}


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


My output:

Array
(
    [json_data] => 
    [json_data.0] => 
    [json_data.0.downtime] => 1
    [json_data.0.pfix] => 
    [json_data.0.pfix.max] => 100
    [json_data.0.pfix.threshold] => 880
    [json_data.0.ints] => 
    [json_data.0.ints.int] => 
    [json_data.0.ints.int.0] => 
    [json_data.0.ints.int.0.rle] => pri
    [json_data.0.ints.int.0.device] => laptop
    [json_data.0.ints.int.0.int] => Ether3
    [json_data.0.ints.int.0.ip] => 127.0.0.3
    [json_data.0.ints.eth] => 
    [json_data.0.ints.eth.lan] => 57
    [json_data.1] => 
    [json_data.1.downtime] => 
    [json_data.1.lsi] => 987654
    [json_data.1.pfix] => 
    [json_data.1.pfix.min] => 10000
    [json_data.1.pfix.threshold] => 890
    [json_data.1.mana] => 
    [json_data.1.mana.mode] => NONE
    [json_data.1.ints] => 
    [json_data.1.ints.int] => 
    [json_data.1.ints.int.0] => 
    [json_data.1.ints.int.0.rle] => sre
    [json_data.1.ints.int.0.device] => desk
    [json_data.1.ints.int.0.int] => Ten
    [json_data.1.ints.int.0.ip] => 1.1.1.1
    [json_data.1.ints.int.0.UF] => 1
    [json_data.1.ints.ethernet] => 
    [json_data.1.ints.ethernet.lan] => 2
)

Solution 18

This is my contribuition

function arrayUnica($array, $prefix = "")
{
    if (!is_array($array)) {
        return false;
    }
    $new_array = [];
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $key = is_int($key) ? $prefix . $key . "-" : $key . "_";
            $new_array = array_merge($new_array, arrayUnica($value, $key));
        } else {
            $new_array[$prefix . $key] = $value;
        }
    }
    return $new_array;
}

Solution 19

I have done this with OOP style

$res=[1=>[2,3,7,8,19],3=>[4,12],2=>[5,9],5=>6,7=>[10,13],10=>[11,18],8=>[14,20],12=>15,6=>[16,17]];
class MultiToSingle{
public $result=[];
public function __construct($array){
    if(!is_array($array)){
        echo "Give a array";
    }
    foreach($array as $key => $value){
        if(is_array($value)){
            for($i=0;$i<count($value);$i++){
                $this->result[]=$value[$i];
            }  
        }else{
            $this->result[]=$value;
        }
    }
}
}

$obj= new MultiToSingle($res);
$array=$obj->result;
print_r($array);

Solution 20

Multi dimensional array to single array with one line code !!! Enjoy the code.

$array=[1=>[2,5=>[4,2],[7,8=>[3,6]],5],4];
$arr=[];
array_walk_recursive($array, function($k){global $arr; $arr[]=$k;});
print_r($arr);

...Enjoy the code.

Solution 21

Try this it works for me:

    $newArray = array();
            foreach($operator_call_logs as $array) {
                foreach($array as $k=>$v) {
                    $newArray[$k] = $v;
                }
            }

Solution 22

Save this as a php file, simply import and use single_array() function

<?php
$GLOBALS['single_array']=[];
function array_conveter($array_list){
    if(is_array($array_list)){
        foreach($array_list as $array_ele){
            if(is_array($array_ele)){
                array_conveter($array_ele);
            }else{
                array_push($GLOBALS['single_array'],$array_ele);
            }
        }
    }else{
        array_push($GLOBALS['single_array'],$array_list);
    }
}
function single_array($mix){
    foreach($mix as $single){
        array_conveter($single);
    }return $GLOBALS['single_array'];
    $GLOBALS['single_array']=[];
}
/* Example convert your multi array to single  */
$mix_array=[3,4,5,[4,6,6,7],'abc'];
print_r(single_array($mix_array));

?>