Related
This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed last month.
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?
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.
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;
}
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'];
Just assign it to it's own first element:
$array = $array[0];
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.
$singleArray = array();
foreach ($multiDimensionalArray as $key => $value){
$singleArray[$key] = $value['plan'];
}
this is best way to create a array from multiDimensionalArray array.
thanks
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());
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"
]
You can do it just using a loop.
$singleArray = array();
foreach ($multiDimensionalArray as $key => $value){
$singleArray[$key] = $value['plan'];
}
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)
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);
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'));
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);
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']);
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.
This simple code you can use
$array = array_column($array, 'value', 'key');
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;
}
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.
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;
}
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;
}
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
)
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;
}
Hope this will helpful for you,
$array= 'YOUR_MULTIDIMENSIONAL_ARRAY';
$arr=[];
array_walk_recursive($array, function($k){global $arr; $arr[]=$k;});
print_r($arr);
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);
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.
Try this it works for me:
$newArray = array();
foreach($operator_call_logs as $array) {
foreach($array as $k=>$v) {
$newArray[$k] = $v;
}
}
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));
?>
if use php version 7.4 and above
$users = [
[
'Ahmed',
'Mohammed',
],
[
'Saeed',
'Rami',
'Haider',
],
];
$admin = array_merge(...$users);
I have a json array like below. I need to get the index into a new array, how is this possible? Arrays are my weakness for some reason just cant grasp them. I can easily get id value, but cannot get the index (e.g 11111111). Any help would be appreciated.
Update please see the revised, my fault for not including the full multi dimensional array.
Below only outputs one result where I need all results.
<?php
$json = '[{
"11111111": {
"id": "val_somevalue5555",
"customer": {
"32312": {
"name": "jane doe"
}
}
},
"2222222": {
"id": "val_somevalue25",
"customer": {
"32312234": {
"name": "jane doe"
}
}
}
}]';
$jsonarr = json_decode($json, true);
$newarr = [];
foreach($jsonarr as $value)
{
$key = key($value);
$newarr[] = ['key' => $key, 'id' => $value[$key]['id']];
}
var_dump($newarr);
expected looped output
key 11111111
id val_somevalue5555
... looped.
You can create an array of the keys of an existing array using the array_keys() function
http://php.net/manual/en/function.array-keys.php
If you don't want the keys in a separate array, and instead just want to access them directly, when you are doing a 'foreach' loop of an array, you can choose to assign a variable to the current key by doing
foreach($jsonarr as $key => $value){...}
Because your original array is actually multidimensional (each $key has a $value that is also stored as an array of "id": "value") - this means taking one more step to get the value of key 'id':
foreach($jsonarr as $key => $value){
$newarray[] = ['key' => $key, 'id' => $value['id'];
}
you can use array_keys() or key() with a foreach loop for this(DEMO):
$newarr = [];
foreach($jsonarr as $value)
{
//$key = array_keys($value)[0];
$key = key($value);
$newarr[] = ['key' => $key, 'id' => $value[$key]['id']];
}
var_dump($newarr);
Output:
array(2) {
[0]=>
array(2) {
["key"]=>
int(11111111)
["id"]=>
string(17) "val_somevalue5555"
}
[1]=>
array(2) {
["key"]=>
int(2222222)
["id"]=>
string(15) "val_somevalue25"
}
}
Edit: With the updated json, you can use the following way, using 2 foreach loops (DEMO):
$newarr = [];
foreach($jsonarr as $json)
{
foreach($json as $key => $value)
{
$newarr[] = ['key' => $key, 'id' => $value['id']];
}
}
PHP supports a slightly different foreach syntax that extracts both the array key and the array value:
foreach ( $jsonarr as $key => $value ) {
$newarr[] = ['key' => $key, 'id' => $value];
}
Use this if you need the key ("11111111" and "2222222" in your example).
<?php
$json = '[{
"11111111": {
"id": "val_somevalue5555"
}
},
{
"2222222": {
"id": "val_somevalue25"
}
}
]';
$jsonarr = json_decode($json, true);
$newarr = [];
foreach($jsonarr as $key => $value) {
$newarr[] = ['key' => key($value), 'id' => current($value)['id']];
}
foreach($newarr as $key) {
echo 'key '.$key['key'] . PHP_EOL;
echo 'id '.$key['id'] . PHP_EOL;
}
If you remove what looks like embedded components in the $json string (otherwise it won't parse) then var_export the output of json_decode() you'll get this:
array (
0 => array (
11111111 => array (
'id' => 'val_somevalue5555',
),
),
1 => array (
2222222 => array (
'id' => 'val_somevalue25',
),
),
)
You have a double-nested array, hence...
foreach ($jsonarr as $obj) {
foreach ($obj as $name=>$value) {
print "$name = $value[id]\n";
break;
}
}
or you can reference the elements directly:
print $jsonarr[0]['11111111']['id'];
First, you are not accessing the deep enough before iterating.
If you call var_export($jsonarr); you will see:
array ( // an indexed array of subarrays
0 =>
array ( // an associative array of subarrays, access via [0] syntax (or a foreach loop that only iterates once)
11111111 => // this is the subarray's key that you want
array (
'id' => 'val_somevalue5555', // this is the value you seek from the id element of 1111111's subarray
'customer' =>
array (
32312 =>
array (
'name' => 'jane doe',
),
),
),
2222222 => // this is the subarray's key that you want
array (
'id' => 'val_somevalue25', // this is the value you seek from the id element of 2222222's subarray
'customer' =>
array (
32312234 =>
array (
'name' => 'jane doe',
),
),
),
),
)
Code: (Demo)
$jsonarr = json_decode($json, true);
$result=[];
// vvvv-avoid a function call (key()) on each iteration by declaring here
foreach($jsonarr[0] as $key=>$subarray){
// ^^^-drill down into the first level (use another foreach loop if there may be more than one)
$result[]=['key'=>$key,'id'=>$subarray['id']];
}
var_export($result);
Output:
array (
0 =>
array (
'key' => 11111111,
'id' => 'val_somevalue5555',
),
1 =>
array (
'key' => 2222222,
'id' => 'val_somevalue25',
),
)
p.s. If $jsonarr has more than one element in its first level, you should use a foreach() loop like this:
foreach($jsonarr as $array1){
foreach($array1 as $key=>$array2){
$result[]=['key'=>$key,'id'=>$array2['id']];
}
}
I currently loop through the array and collect values into another array.
foreach($percentage_array[$scenario_first] as $type => $value) {
$first = substr($type,0,$first_letters_count);
if(strlen($type)==$sc_type) {
if($first==$scenario) {
$percentages[] = $value;
$scenario_array[$type] = $value;
}
}
}
Instead of looping through the array, i want to get all keys that begin with x e.g. xaa, xab, xac
So instead i do $percentage_array[$scenario_first][beginning_with_x]
How do i do this?
EDIT: This is even easier:
$filtered_array = array_filter($array, function($key){
return $key{0} == 'x';
}, ARRAY_FILTER_USE_KEY);
Giving:
array(3) {
["xa"]=>
int(1)
["xb"]=>
int(2)
["xd"]=>
int(4)
}
https://3v4l.org/Zri7n
Original answer:
Not quite sure if I understand the example code, but if you want to remove all key/value pairs in an array based on whether it begins with a letter, you can:
$array = [
'xa' => 1,
'xb' => 2,
'yc' => 3,
'xd' => 4,
];
$filtered_keys = array_filter(array_keys($array), function($k){
return !($k{0} == 'x');
});
foreach ($filtered_keys as $v) {
unset($array[$v]);
}
https://3v4l.org/6810T
Didn't try to understand your question fully, but maybe this is what you are looking for, give it a try & do modification according to your need
$percentage_array = array(
'xaa' => 1,
'xab' => 1,
'xac' => 1,
'non' => 1,
'sox' => 1);
$pattern = "/^x(.*)/";
$filtered_array = preg_filter($pattern, "$0", array_keys( $percentage_array ));
echo "<pre>";
print_r($filtered_array);
Below is the output
Array
(
[0] => xaa
[1] => xab
[2] => xac
)
To be short, I have two simple arrays and I want to verify if certain keys from the second array have empty values and replace them with their correspondent values from the first array.
Example:
$a1 = [ 1 => 'one', 2 => 'two', 3 => 'three',5=>'cinco', 6=>'six'];
$a2 = [ 2 => 'two', 5=>'five', 6=>'' ];
Result:
Array
(
[2] => two
[5] => five
[6] => six
)
The following code works already for this.
$keys = array_keys($a1);
foreach ($keys as $k)
{
if ((isset($a2[$k])) && (($a2[$k]) == '')) {
$a2[$k] = $a1[$k];
}
}
print_r($a2);
But what if we want to apply this for two 2D arrays? What will be the proper approach in that case? Let's say these two 2D arrays will be:
$superheroes_complete = array(
"spiderman" => array(
"name" => "Peter Parker",
"email" => "peterparker#mail.com",
),
"superman" => array(
"name" => "Clark Kent",
"email" => "clarkkent#mail.com",
),
"ironman" => array(
"name" => "Harry Potter",
"email" => "harrypotter#mail.com",
)
);
$superheroes_empty = array(
"spiderman" => array(
"name" => "Peter Parker",
"email" => "",
),
"superman" => array(
"name" => "Clark Kent",
"email" => "something",
),
"ironman" => array(
"name" => "Harry Potter",
"email" => "another one",
)
);
Expectation:
$superheroes = array(
"spider-man" => array(
"name" => "Peter Parker",
"email" => "peterparker#mail.com",
),
"super-man" => array(
"name" => "Clark Kent",
"email" => "something",
),
"iron-man" => array(
"name" => "Harry Potter",
"email" => "another one",
)
);
Much appreciation and thank you in advance!
You've added another level to your data, so you can just add another level to your checking as well with a second foreach loop:
foreach ($superheroes_complete as $hero => $info) {
foreach ($info as $key => $value) {
if (empty($superheroes_empty[$hero][$key])) {
$superheroes_empty[$hero][$key] = $value;
}
}
}
First note that your 1D case can be simplified:
foreach ($a2 as $k => $v) {
if (!isset($v)) {
$a2[$k] = $a1[$k];
}
}
Then for the 2D case, assuming the 1st level keys are always the same (or it becomes a quite different question!):
foreach ($superheroes_complete as $main_k => $main_v) {
foreach ($main_v as $k => $v) {
if (!isset($v)) {
$superheroes_empty[$main_k][$k] = $superheroes_complete[$main_k][$k];
}
}
If you only need to take care of the "email" field you can do this :
<?php
$keys = array_keys($superheroes_complete);
foreach ($keys as $k)
{
if ((isset($superheroes_empty[$k]["email"])) &&
(($superheroes_empty[$k]["email"]) == '')) {
$superheroes_empty[$k]["email"] = $superheroes_complete[$k]["email"];
}
}
var_dump($superheroes_empty);
?>
For the generic case where the depth of nesting is unlimited, you could use this recursive function:
function fillEmpty(&$filled, &$empty) { // arguments are by reference
if ($empty === "") {
$empty = $filled;
return;
}
if (!is_array($filled) || !is_array($empty)) return;
foreach ($filled as $key => $value) {
if (isset($empty[$key])) fillEmpty($value, $empty[$key]);
}
}
Example call:
fillEmpty($superheroes_complete, $superheroes_empty);
This modifies the second argument, filling the empty values.
See it run on eval.in
It might be your lucky day, php has some built in functions to compare arrays values and keys. Use array_diff() which can compare two or more arrays and return the difference. You could also use array_intersect() which does the opposite.
If you want to only compare the keys, use array_diff_key()which returns only the key difference or array_intersect_key() which returns the matched keys.
You could also consider a recursive solution. This could work on both the 1D and 2D arrays, or even an array of N dimensions.
I'm aware that recursion should be used with care, as it can be quite resource intensive. This is however a more versatile solution, and keeps the code cleaner with less nested control structures and early returns, which I find better readable. I'll use the native array_walk method because I was taught that it should perform better then a php loop.
So this is what my code would look like:
function array_complement_recursive(&$partial, $complete) {
array_walk($partial, function(&$value, $key) use ($complete) {
// (for safety) complete does not contain matching key: done
if (! array_key_exists($key, $complete)) {
return;
}
// value is array: call recursive
if (is_array($value)) {
array_complement_recursive($value, $complete[$key]);
return;
}
// value is not 'empty': done
// note that null, 0, false will also not match, you may want to make
// this check more specific to match only the empty string
if ($value) {
return;
}
$value = $complete[$key];
});
}
I've set up a little demo so you can see that it works on both your examples. And as I said, it should even work for arrays with more dimensions, or a more irregular structure.
http://phpfiddle.org/main/code/49iz-vrwg
I've added some comments to explain, but feel free to ask if anything is unclear.
This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed last month.
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?
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.
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;
}
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'];
Just assign it to it's own first element:
$array = $array[0];
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.
$singleArray = array();
foreach ($multiDimensionalArray as $key => $value){
$singleArray[$key] = $value['plan'];
}
this is best way to create a array from multiDimensionalArray array.
thanks
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());
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"
]
You can do it just using a loop.
$singleArray = array();
foreach ($multiDimensionalArray as $key => $value){
$singleArray[$key] = $value['plan'];
}
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)
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);
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'));
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);
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']);
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.
This simple code you can use
$array = array_column($array, 'value', 'key');
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;
}
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.
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;
}
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;
}
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
)
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;
}
Hope this will helpful for you,
$array= 'YOUR_MULTIDIMENSIONAL_ARRAY';
$arr=[];
array_walk_recursive($array, function($k){global $arr; $arr[]=$k;});
print_r($arr);
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);
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.
Try this it works for me:
$newArray = array();
foreach($operator_call_logs as $array) {
foreach($array as $k=>$v) {
$newArray[$k] = $v;
}
}
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));
?>
if use php version 7.4 and above
$users = [
[
'Ahmed',
'Mohammed',
],
[
'Saeed',
'Rami',
'Haider',
],
];
$admin = array_merge(...$users);