how to flatten a multidimensional array in php [duplicate] - php

This question already has answers here:
How to Flatten a Multidimensional Array?
(31 answers)
Closed 1 year ago.
This is my array and i want 60 , 20, 39, 70,12, 29,31,72,59 in a single array. one-dimensional array.
$marks = array(
"abc" => array(
"a" => 60,
"b" => 20,
"c" => 39
),
"def" => array(
"a" => 70,
"b" => 12,
"c" => 29
),
"xyz" => array(
"a" => 31,
"b" => 72,
"c" => 59
)
)Íž
my try was
foreach($marks as $name=>$score)
{
foreach($score as $subject=>$number)
{
$array[]= $number;
}
}
But when i am printing this array it again generate three array.
on print_r($array); its showing this output.
Array ( [0] => 60 [1] => 20 [2] => 39 ) Array ( [0] => 60 [1] => 20 [2] => 39 [3] => 70 [4] => 12 [5] => 29 ) Array ( [0] => 60 [1] => 20 [2] => 39 [3] => 70 [4] => 12 [5] => 29 [6] => 31 [7] => 72 [8] => 59 )
is there any method to get only last array from the above array.or any other solution.

Try this to flatten the array:
<?php
$marks = array(
"abc" => array(
"a" => 60,
"b" => 20,
"c" => 39
),
"def" => array(
"a" => 70,
"b" => 12,
"c" => 29
),
"xyz" => array(
"a" => 31,
"b" => 72,
"c" => 59
)
);
function array_values_recursive($array)
{
$arrayValues = array();
foreach ($array as $value)
{
if (is_scalar($value) OR is_resource($value))
{
$arrayValues[] = $value;
}
elseif (is_array($value))
{
$arrayValues = array_merge($arrayValues, array_values_recursive($value));
}
}
return $arrayValues;
}
var_dump(array_values_recursive($marks));
Output:
array(9) { [0]=> int(60) [1]=> int(20) [2]=> int(39) [3]=> int(70) [4]=> int(12) [5]=> int(29) [6]=> int(31) [7]=> int(72) [8]=> int(59) }
This custom function was taken from: http://php.net/manual/en/function.array-values.php

you can do in either traditional way i.e. foreach loop and also can use iterator. have a look on below solution:
1) using foreach loop and array_merge function
$marks = array(
"abc" => array(
"a" => 60,
"b" => 20,
"c" => 39
),
"def" => array(
"a" => 70,
"b" => 12,
"c" => 29
),
"xyz" => array(
"a" => 31,
"b" => 72,
"c" => 59
)
);
$new_array = array();
foreach ($marks as $mark) {
$new_array = array_merge($new_array, array_values($mark));
}
print_r($new_array);
2) using ArrayIterator:
$new_array = array();
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($marks));
foreach ($iterator as $key => $value) {
$new_array[] = $value;
}
print_r($new_array);
In both solution Output will be:
Array
(
[0] => 60
[1] => 20
[2] => 39
[3] => 70
[4] => 12
[5] => 29
[6] => 31
[7] => 72
[8] => 59
)

Because you're dumping $array inside the first foreach loop :)

Your sound like you may be declare your $array in for loop ,if you do so you will get three arrays.So declare outside of for loop will be get single array
$array = array(); //correct
foreach($marks as $name=>$score)
{
//$array = array(); //incorrect
foreach($score as $subject=>$number)
{
$array[]= $number;
}
}
var_dump($array);

foreach($marks as $name=>$score)
{
foreach($score as $subject=>$number)
{
$array[]= $number;
}
}

Related

PHP array_multisort not sorting with double multidimensional array as expected

Here's my code.
<?php
$data['test1'][0] = array('total' => 67, 'edition' => 2, 'pkg_version' => "2.5.0" );
$data['test1'][1] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.1.0" );
$data['test1'][2] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.3.0" );
$data['test2'][0] = array('total' => 86, 'edition' => 1, 'pkg_version' => "1.5.0");
$data['test2'][1] = array('total' => 85, 'edition' => 6, 'pkg_version' => "0.53.0");
$data['test2'][2] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.3");
$data['test2'][3] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.2");
$data['test3'][0] = array('total' => 60, 'edition' => 6, 'pkg_version' => "0.3");
$data['test3'][1] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.1.1");
$data['test3'][2] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.25");
foreach ($data as $row) {
foreach ($row as $k){
foreach ($k as $key => $value){
${$key}[] = $value;
}
}
}
array_multisort($pkg_version, SORT_DESC, $data);
echo "<pre>";
print_r($data);
echo "</pre>";
?>
I am trying to sort a multidimensional array using the array_multisort function
I would like to sort the pkg_version of each element to be ordered
The returned order is not as expected. Not sure, I have misunderstood how
array_multisort works? or my code is wrong. could you guys help me? I try to
solve this problem for a long time. it's quite a complex dimension array.
Here's the result after running the code above.
Array
(
[test1] => Array
(
[0] => Array
(
[total] => 67
[edition] => 2
[pkg_version] => 2.5.0
)
[1] => Array
(
[toal] => 67
[edition] => 2
[pkg_version] => 0.1.0
)
[2] => Array
(
[total] => 67
[edition] => 2
[pkg_version] => 0.3.0
)
)
[test2] => Array
(
[0] => Array
(
[total] => 86
[edition] => 1
[pkg_version] => 1.5.0
)
[1] => Array
(
[total] => 85
[type] => 2
[pkg_version] => 0.53.0
)
[2] => Array
(
[total] => 98
[type] => 2
[pkg_version] => 0.3
)
[3] => Array
(
[total] => 98
[edition] => 2
[pkg_version] => 0.2
)
)
[test3] => Array
(
[0] => Array
(
[total] => 60
[edition] => 6
[pkg_version] => 0.3
)
[1] => Array
(
[total] => 60
[edition] => 7
[pkg_version] => 0.1.1
)
[2] => Array
(
[total] => 60
[edition] => 7
[pkg_version] => 0.25
)
)
)
This is what I expected.
Array
(
[test1] => Array
(
[0] => Array
(
[total] => 67
[edition] => 2
[pkg_version] => 2.5.0
)
[1] => Array
(
[total] => 67
[edition] => 2
[pkg_version] => 0.3.0
)
[2] => Array
(
[toal] => 67
[edition] => 2
[pkg_version] => 0.1.0
)
)
[test2] => Array
(
[0] => Array
(
[total] => 86
[edition] => 1
[pkg_version] => 1.5.0
)
[1] => Array
(
[total] => 85
[type] => 2
[pkg_version] => 0.53.0
)
[2] => Array
(
[total] => 98
[type] => 2
[pkg_version] => 0.3
)
[3] => Array
(
[total] => 98
[edition] => 2
[pkg_version] => 0.2
)
)
[test3] => Array
(
[0] => Array
(
[total] => 60
[edition] => 6
[pkg_version] => 0.3
)
[1] => Array
(
[total] => 60
[edition] => 7
[pkg_version] => 0.25
)
[2] => Array
(
[total] => 60
[edition] => 7
[pkg_version] => 0.1.1
)
)
)
You can loop over the array and use usort()
<?php
$data['test1'][0] = array('total' => 67, 'edition' => 2, 'pkg_version' => "2.5.0" );
$data['test1'][1] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.1.0" );
$data['test1'][2] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.3.0" );
$data['test2'][0] = array('total' => 86, 'edition' => 1, 'pkg_version' => "1.5.0");
$data['test2'][1] = array('total' => 85, 'edition' => 6, 'pkg_version' => "0.53.0");
$data['test2'][2] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.3");
$data['test2'][3] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.2");
$data['test3'][0] = array('total' => 60, 'edition' => 6, 'pkg_version' => "0.3");
$data['test3'][1] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.1.1");
$data['test3'][2] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.25");
// use a reference to the sub array
// |
// |
// v
foreach ($data as &$row)
{
usort($row, function($a, $b)
{
// make a desc sort by comparing $b against $a instead of $a against $b
return strcmp($b['pkg_version'], $a['pkg_version']);
});
}
var_dump($data);
This outputs :
array(3) {
["test1"]=>
array(3) {
[0]=>
array(3) {
["total"]=>
int(67)
["edition"]=>
int(2)
["pkg_version"]=>
string(5) "2.5.0"
}
[1]=>
array(3) {
["total"]=>
int(67)
["edition"]=>
int(2)
["pkg_version"]=>
string(5) "0.3.0"
}
[2]=>
array(3) {
["total"]=>
int(67)
["edition"]=>
int(2)
["pkg_version"]=>
string(5) "0.1.0"
}
}
["test2"]=>
array(4) {
[0]=>
array(3) {
["total"]=>
int(86)
["edition"]=>
int(1)
["pkg_version"]=>
string(5) "1.5.0"
}
[1]=>
array(3) {
["total"]=>
int(85)
["edition"]=>
int(6)
["pkg_version"]=>
string(6) "0.53.0"
}
[2]=>
array(3) {
["total"]=>
int(98)
["edition"]=>
int(2)
["pkg_version"]=>
string(3) "0.3"
}
[3]=>
array(3) {
["total"]=>
int(98)
["edition"]=>
int(2)
["pkg_version"]=>
string(3) "0.2"
}
}
["test3"]=>
&array(3) {
[0]=>
array(3) {
["total"]=>
int(60)
["edition"]=>
int(6)
["pkg_version"]=>
string(3) "0.3"
}
[1]=>
array(3) {
["total"]=>
int(60)
["edition"]=>
int(7)
["pkg_version"]=>
string(4) "0.25"
}
[2]=>
array(3) {
["total"]=>
int(60)
["edition"]=>
int(7)
["pkg_version"]=>
string(5) "0.1.1"
}
}
}
Note that in the last array, the version 0.3 is higher than the version 0.25. Since it's the order in your expected output, I left it as is, but if not, you can use instead of strcmp(), version_compare(), this will provide this output for $data['test3'] :
["test3"]=>
&array(3) {
[0]=>
array(3) {
["total"]=>
int(60)
["edition"]=>
int(7)
["pkg_version"]=>
string(4) "0.25"
}
[1]=>
array(3) {
["total"]=>
int(60)
["edition"]=>
int(6)
["pkg_version"]=>
string(3) "0.3"
}
[2]=>
array(3) {
["total"]=>
int(60)
["edition"]=>
int(7)
["pkg_version"]=>
string(5) "0.1.1"
}
}
}

Merging multi dimensional array in PHP

I have 2 array as below(Array-1, Array-2) and i wanted to merge as a single array as below (New-Array) based on the below condition
Contition : (if Array-1(hID) = Array-2(hID) then megre as below)
Array-1
Array
(
[0] => Array
(
[hID] => 107
[env] => DEV
[serv] => server1
)
[1] => Array
(
[hID] => 122
[env] => DEV
[serv] => server2
)
Array-2
Array
(
[107] => Array
(
[hID] => 107
[cpu] => 32
[mem] => 24
)
[122] => Array
(
[hID] => 122
[cpu] => 16
[mem] => 24
)
New-Array
Array
(
[0] => Array
(
[hID] => 107
[env] => DEV
[serv] => server1
[cpu] => 32
[mem] => 24
)
[1] => Array
(
[hID] => 122
[env] => DEV
[serv] => server2
[cpu] => 16
[mem] => 24
)
If second array always has same keys as hID values then you can do the following:
$newArray = [];
foreach ($array1 as $item) {
if (isset($array2[$item['hID']])) {
$newArray[] = array_merge($item, $array2[$item['hID']]);
}
}
Or you can always create such array (key is the same as hID value) with:
$array2 = array_combine(
array_column($array2, 'hID'),
$array2
);
You can try this :
The test arrays :
$array_1 = [
0 => [
"hID" => 107,
"env" => "DEV",
"serv" => "server1"
],
1 => [
"hID" => 122,
"env" => "DEV",
"serv" => "server2"
]
];
$array_2 = [
0 => [
"hID" => 107,
"cpu" => 32,
"mem" => 24
],
1 => [
"hID" => 122,
"cpu" => 16,
"mem" => 24
]
];
The code to merge both arrays :
$new_array = [];
for($i=0;$i<count($array_1);$i++) {
for($j=0;$j<count($array_2);$j++) {
if ($array_1[$i]['hID'] === $array_2[$j]['hID']) {
$new_array[] = array_merge($array_1[$i], $array_2[$j]);
}
}
}
The output :
var_dump($new_array);
array(2) {
[0]=>
array(5) {
["hID"]=>
int(107)
["env"]=>
string(3) "DEV"
["serv"]=>
string(7) "server1"
["cpu"]=>
int(32)
["mem"]=>
int(24)
}
[1]=>
array(5) {
["hID"]=>
int(122)
["env"]=>
string(3) "DEV"
["serv"]=>
string(7) "server2"
["cpu"]=>
int(16)
["mem"]=>
int(24)
}
}
Test here : http://sandbox.onlinephpfunctions.com/
if($array1[hID] == $array2[hID]){
$Array3 = array_merge($array1, $array2);
}

get the last common array value in PHP dynamically

I have original array as given below
$orginal_arra = Array(
[0] => 53_0.1,
[1] => 53_0.3,
[2] => 54_0.2,
[3] => 54_0.1,
[4] => 54_0.1,
[5] => 54_0.19,
[6] => 56_0.19,
[7] => 56_0.50
);
The above array can explode by "_" separating
foreach($orginal_arra as $part) {
if($part){
$arr_parts = explode("_",$part);
$arr1[] = $arr_parts[0];
$arr2[] = $arr_parts[1];
}
}
The $arr1 result after sperating
Array (
[0] => 53,
[1] => 53,
[2] => 54,
[3] => 54,
[4] => 54,
[5] => 54,
[6] => 56,
[7] => 56
)
The $arr2 result after sperating
Array (
[0] => 0.1,
[1] => 0.3,
[2] => 0.2,
[3] => 0.1,
[4] => 0.1,
[5] => 0.19,
[6] => 0.19,
[7] => 0.50
)
I want to return the array by combining $arr1 and $arr2 as like
$array = Array(
[0] => 53_0.3,
[1] => 54_0.19,
[2] => 56_0.50
);
Is there any way to get the result like above using PHP Arrays.
You can use array_values on grouping the array into an associative array. Use array_values to convert the associative array into a simple array.
$orginal_arra = array(
'53_0.1',
'53_0.3',
'54_0.2',
'54_0.1',
'54_0.1',
'54_0.19',
'56_0.19',
'56_0.50'
);
$result = array_values(array_reduce($orginal_arra, function($c,$v){
$key = explode('_', $v); //explode the value
$c[$key[0]] = $v; //Use the first element of the explode value as a key and just overide the value
return $c;
}, array()));
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[0] => 53_0.3
[1] => 54_0.19
[2] => 56_0.50
)
strstr() is the perfect temporary key generator. Each recurring key will overwrite the previous value. When the loop finishes, just reindex the result array with array_values(). Clean and simple.
Code: (Demo)
$original_array = Array(
'53_0.1',
'53_0.3',
'54_0.2',
'54_0.1',
'54_0.1',
'54_0.19',
'56_0.19',
'56_0.50'
);
foreach ($original_array as $v) {
$result[strstr($v, "_", true)] = $v;
}
var_export(array_values($result));
Output:
array (
0 => '53_0.3',
1 => '54_0.19',
2 => '56_0.50',
)
You can do this if you want to combine $array1 and $array2:
<?php
$array1= array(
"0" => 53,
"1" => 53,
"2" => 54,
"3" => 54,
"4" => 54,
"5" => 54,
"6" => 56,
"7" => 56
);
$array2 = array (
"0" => 0.1,
"1" => 0.3,
"2" => 0.2,
"3" => 0.1,
"4" => 0.1,
"5" => 0.19,
"6" => 0.19,
"7" => 0.50
);
$array1 = array_reverse($array1, true);
$array1 = array_unique($array1);
foreach($array1 as $key=>$val){
$array1[$key] = $val."_".number_format((float)$array2[$key], 2, '.', '');
}
print_r(array_reverse($array1));
Output:
Array
(
[0] => 53_0.30,
[1] => 54_0.19,
[2] => 56_0.50
)

PHP Array manipulation need tips

I have arrays in one submission, please see below details:
array(5) {
["ambition_id"]=>
array(2) {
[55]=> string(2) "55"
[60]=> string(2) "60"
}
["target"]=>
array(1) {
[0]=> string(8) "target 1"
[1]=> string(8) "target 2"
}
["strides"]=>
array(1) {
[0]=> string(1) "1"
[1]=> string(1) "1"
}
["date"]=>
array(1) {
[0]=> string(10) "2017-02-08"
[1]=> string(10) "2017-03-08"
}
["frequency"]=>
array(1) {
[0]=> string(1) "1"
[1]=> string(1) "2"
}
}
Actually, I have two tables in mysql, 'ambition' and 'target'. Ambition is a group of targets ('ambition_id' is foreign key in 'target' table). That array will be stored in 'target' table. That's why there is an 'ambition_id'
I've tried many times but failed (using foreach), now I need someone who can give me a help.
By brute force, It's easy! I solved it already but I need "more advanced" array manipulation.
How can I come up into this?
array(2) {
[0] => array('ambition_id' => 55,
'target' => 'target 1',
'strides' => 1,
'date' => '2017-02-08',
'frequency' => 1
),
[1] => array('ambition_id' => 60,
'target' => 'target 2',
'strides' => 2,
'date' => '2017-03-08',
'frequency' => 2)
}
Please do help, many thanks!
You have to pivot your data:
$data = array (
"ambition_id" =>
array (
55 => "55",
60 => "60"
),
"target" =>
array (
0 => "target 1",
1 => "target 2"
),
"strides" =>
array (
0 => "1",
1 => "1"
),
"date" =>
array (
0 => "2017-02-08",
1 => "2017-03-08"
),
"frequency" =>
array (
0 => "1",
1 => "2"
)
);
// pivot data
$pivot = array();
foreach ($data as $datum => $values) {
$value_index = 0;
foreach ($values as $value) {
$pivot[$value_index][$datum] = $value;
$value_index++;
}
}
print_r($pivot);
This assumes you only have two levels of data and that the data is well behaved.
Not the best answer, but it solves your problem
<?php
$array = [
"ambition_id" =>
[
55 => "55",
60 => "60"
],
"target" =>
[
0 => "target 1",
1 => "target 2"
],
"strides" =>
[
0 => "1",
1 => "1"
],
"date" =>
[
0 => "2017-02-08",
1 => "2017-03-08"
],
"frequency" =>
[
0 => "1",
1 => "2"
],
];
$result = array();
foreach ($array as $k => $v) {
foreach ($v as $kk => $vv) {
if ($k == "ambition_id") {
$result[] = array($k => $vv);
} else {
$result[$kk][$k] = $vv;
}
}
}
Here is the test https://3v4l.org/UdHH8
Just use loop the array and user array_values to re-index the loop the inner array and store it into new array like below .
<?php
$new_array =array();
foreach($array as $key1=>$row1 )
{
$ss =array_values($row1);
foreach($ss as $key2=>$row2)
{
$new_array[$key2][$key1]=$row2;
}
}
echo "<pre>";
print_r($new_array);
?>
Output :
Array
(
[0] => Array
(
[ambition_id] => 55
[target] => target 1
[strides] => 1
[date] => 2017-02-08
[frequency] => 1
)
[1] => Array
(
[ambition_id] => 60
[target] => target 2
[strides] => 1
[date] => 2017-03-08
[frequency] => 2
)
)

How to merge these 2 arrays in PHP?

I have an array $array1 with different amount of key and value pairs:
Array
(
[0] => Array
(
[ID] => 39
[title] => Apple
)
[1] => Array
(
[ID] => 40
[title] => Orange
)
)
and another array $array2:
Array
(
[0] => 273
[1] => 386
)
And I want to get this:
Array
(
[0] => Array
(
[ID] => 39
[title] => Apple
[pages] => 273
)
[1] => Array
(
[ID] => 40
[title] => Orange
[pages] => 386
)
)
The number of items in each array is the same and the correspond, so, we don't need to check this, so, how to merge it like that?
use array_replace_recursive if you want merge with integer keys, or array_merge_recursive if you want merge only string keys
<?php
$a1 = array(
0 => array
(
"ID" => 39,
"title" => "Apple"
),
1 => array(
"ID" => 40,
"title" => "Orange"
)
);
$a2 = array(
0 => array
(
"pages" => 273,
"year" => 1981
),
1 => array(
"pages" => 386,
"year" => 1979
)
);
$a3 = array_replace_recursive($a1, $a2);
var_dump($a3);
Result:
array(2) {
[0] =>
array(4) {
'ID' =>
int(39)
'title' =>
string(5) "Apple"
'pages' =>
int(273)
'year' =>
int(1981)
}
[1] =>
array(4) {
'ID' =>
int(40)
'title' =>
string(6) "Orange"
'pages' =>
int(386)
'year' =>
int(1979)
}
}
Answer for updated question:
<?php
$a1 = array(
0 => array
(
"ID" => 39,
"title" => "Apple"
),
1 => array(
"ID" => 40,
"title" => "Orange"
)
);
$a2 = array(
0 => 31,
1 => 324
);
$defaultValue = 0;
foreach ($a1 as $key => $value) {
$a1[$key]['pages'] = isset($a2[$key]) ? $a2[$key] : $defaultValue;
}
var_dump($a1);
Result:
array(2) {
[0] =>
array(3) {
'ID' =>
int(39)
'title' =>
string(5) "Apple"
'pages' =>
int(31)
}
[1] =>
array(3) {
'ID' =>
int(40)
'title' =>
string(6) "Orange"
'pages' =>
int(324)
}
}
Try this code :-
$newArray = array();
$i=0;
foreach($array1 as $value){
$newArray[$i] = $value;
$newArray[$i][] = $array2[$i];
$i++;
}
Here is code that produce exactly output you are looking for :
<?php
$list1 = array(array('id' => 39,'title' => 'Apple'),array('id' => 40,'title' => 'Orange'));
$list2 = array(array('pages' => 273,'year' => 1981),array('pages' => 386,'year' => 1979));
$newList = array();
$i=0;
foreach($list1 as $firstList){
foreach($list2 as $secondList){
$newList[$i] = array_merge($firstList, $secondList);
}
$i++;
}
echo"<pre>"; print_r($newList); echo"</pre>";
?>
OUTPUT :
Try this
array1[0][pages]=array2[0][pages];
array1[0][year]=array2[0][year];
array1[1][pages]=array2[1][pages];
array1[1][year]=array2[1][year];
for($i=0; $i<count($array1); ++$i){
$array1[$i]['pages'] = $array2[$i];
}
var_dump($array1);
$output = array();
array_walk( $array1, function( $v, $k ) use ( $array2, &$output ) {
$output[] = array_merge( $v, $array2[$k] );
});
If the sizes of the 2 arrays are same you could do something like this
$arr1 = array(
array(
'ID' => 39,
'title' => 'Apple'
),
array(
'ID' => 40,
'title' => 'Orange'
)
);
$arr2 = array(
273,
386
);
$merged = array();
for ($i = 0; $i < count($arr1); $i++) {
$merged[] = array_merge($arr1[$i], array('pages' => $arr2[$i]));
}
var_dump($merged);
or if you don't want a new array
for ($i = 0; $i < count($arr1); $i++) {
$arr1[$i]['pages'] = $arr2[$i];
}

Categories