I have an array which comes out by calling a recursion function on the basis of parent id. This array is an n level multidimensional array.
What I want is to break this array into single dimensional, so that every child comes just after their parent.
I am using following function to first convert into recursive tree.
function formatTree($tree, $parent){
$tree2 = array();
foreach($tree as $i => $item){
if($item['cat_parent_id'] == $parent){
$tree2[$item['cat_id']] = $item;
$tree2[$item['cat_id']]['submenu'] = formatTree($tree, $item['cat_id']);
}
}
return $tree2;
}
This is the array I have.
Array
(
[58] => Array
(
[cat_id] => 58
[cat_name] => Desserts
[cat_parent_id] => 0
[submenu] => Array
(
[535] => Array
(
[cat_id] => 535
[cat_name] => dessert child
[cat_parent_id] => 58
[submenu] => Array
(
)
)
)
)
[56] => Array
(
[cat_id] => 56
[cat_name] => Biryani & Rice
[cat_parent_id] => 0
[submenu] => Array
(
)
)
)
This is how I want this.
Array
(
[0] => Array
(
[cat_id] => 58
[cat_name] => Desserts
[cat_parent_id] => 0
[submenu] => Array
(
)
)
[1] => Array
(
[cat_id] => 535
[cat_name] => dessert child
[cat_parent_id] => 58
[submenu] => Array
(
)
)
[2] => Array
(
[cat_id] => 56
[cat_name] => Biryani & Rice
[cat_parent_id] => 0
[submenu] => Array
(
)
)
)
It's almost 2020. I know it's a bit late but for those who are googling around: Their answers were close but they're only returning the parent elements. I've tweaked it a little bit to make it work (using array_merge).
function array_single_dimensional($items)
{
$singleDimensional = [];
foreach ($items as $item) {
$children = isset($item['children']) ? $item['children'] : null; //temporarily store children if set
unset($item['children']); //delete children before adding to new array
$singleDimensional[] = $item; // add parent to new array
if ( !empty($children) ){ // if has children
//convert children to single dimensional
$childrenSingleDimensional = array_single_dimensional($children);
//merge the two, this line did the trick!
$singleDimensional = array_merge($singleDimensional, $childrenSingleDimensional);
}
}
return $singleDimensional;
}
$singleDimensionalArray = array_single_dimensional($multidimensionalArray);
So, I assume you can change your initial function to make an array like the second one... then you should update your function like this:
function formatTree($tree, $parent){
$tree2 = array();
foreach($tree as $i => $item){
if($item['cat_parent_id'] == $parent){
$item['submenu'] = array();
$tree2[] = $item;
formatTree($tree, $item['cat_id']);
}
}
return $tree2;
}
This should work. For your use case you don't need a parent_id in your function.
function formatTree($tree){
$tree2 = array();
foreach($tree as $i => $item){
$submenu = $item['submenu'];
unset($item['submenu']); //clear submenu of parent item
$tree2[] = $item;
if(!empty($submenu)){
$sub = formatTree($submenu); //submenu's return as array in array
$tree2[] = $sub[0]; // remove outer array
}
}
return $tree2;
}
Just try this,
$array = Array
(
"58" => Array
(
"cat_id" => 58,
"cat_name" => "Desserts",
"cat_parent_id" => 0,
"submenu" => Array
(
"535" => Array
(
"cat_id" => 535,
"cat_name" => "dessert child",
"cat_parent_id" => 58,
"submenu" => Array
()
)
)
),
"56" => Array
(
"cat_id" => 56,
"cat_name" => "Biryani & Rice",
"cat_parent_id" => 0,
"submenu" => Array
()
)
);
function singledimensional($array)
{
$res = array();
foreach ($array as $i => $item) {
$temparr = $item;
$item['submenu'] = array();
$res[] = $item;
if (!empty($temparr['submenu']) ){
$child = singledimensional($temparr['submenu']);
$res[] = $child[0];
}
}
return $res;
}
echo '<pre>';
print_r(singledimensional($array));
echo '</pre>';
Output:
Array
(
[0] => Array
(
[cat_id] => 58
[cat_name] => Desserts
[cat_parent_id] => 0
[submenu] => Array
(
)
)
[1] => Array
(
[cat_id] => 535
[cat_name] => dessert child
[cat_parent_id] => 58
[submenu] => Array
(
)
)
[2] => Array
(
[cat_id] => 56
[cat_name] => Biryani & Rice
[cat_parent_id] => 0
[submenu] => Array
(
)
)
)
I hope this will help you :)
(PHP 4 >= 4.0.1, PHP 5)
array_merge_recursive — Merge two or more arrays recursively
`function array_merge_recursive_distinct ( array &$array1, array &$array2 )
{
$merged = $array1;
foreach ( $array2 as $key => &$value )
{
if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) )
{
$merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
}
else
{
$merged [$key] = $value;
}
}
return $merged;
}
?>`
Related
We have and array like below in PHP, and want to create a new array in the new array there should be the unique key and the value from the same key should be added.
Array
(
[0] => Array
(
[58] => 32.00
)
)
Array
(
[0] => Array
(
[58] => 34.00
)
)
Array
(
[0] => Array
(
[57] => 26.00
)
)
Array
(
[0] => Array
(
[57] => 27.00
)
)
Array
(
[0] => Array
(
[56] => 16.00
)
)
Array
(
[0] => Array
(
[56] => 17.00
)
)
We want to create new array with the help of the above array.
The value of same key should be added.
The output of new array should be like below.
Array
(
[58] => 66
[57] => 53
[56] => 33
)
code is below
The output of minmaxarray is
Array
(
[0] => Array
(
[min] => 35.00
[max] => 50.00
[price] => 26.00
)
[1] => Array
(
[min] => 50.00
[max] => 80.00
[price] => 29.00
)
[2] => Array
(
[min] => 80.00
[max] => 100.00
[price] => 32.00
)
[3] => Array
(
[min] => 100.00
[max] => 150.00
[price] => 34.00
)
[4] => Array
(
[min] => 150.00
[max] => 180.99
[price] => 36.00
)
)
$shippingPrice = array();
foreach ($minmaxarray as $key => $value) {
if($price > $value['min'] && $price < $value['max'])
{
if($value['price'])
{
$shippingPrice[][$smethodid] = $value['price'];
break;
}
}
}
echo '<pre>'; print_r ($shippingPrice);
Thanks
If your array structure is always the same like you have posted, then this code will work for you:
$example_array = array(
array( '0' => 32.00 ),
array( '2' => 32.00 ),
array( '2' => 32.00 )
);
$new_array = array();
// loop through every item in nested foreach
foreach( $example_array as $value ) {
foreach( $value as $key => $number ) {
// if the array key not exist, calculate with 0, otherwise calculate with the actual value
$new_array[$key] = isset($new_array[$key]) ? $new_array[$key] + $number : 0 + $number;
}
}
print_r( $new_array );
// prints Array ( [0] => 32 [2] => 64 )
Code example for your arrays:
$shippingPrice = array();
// loop through every item in nested foreach
foreach( $minmaxarray as $value ) {
foreach( $value as $key => $number ) {
// if the array key not exist, calculate with 0, otherwise calculate with the actual value
$shippingPrice[$key] = isset($shippingPrice[$key]) ? $shippingPrice[$key] + $number : 0 + $number;
}
}
echo '<pre>';
print_r( $shippingPrice );
You can try this code
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;
}
You call this function by your array then function will return your expected array.
array_flatten($array);
You can use array_walk_recursive instead of 2 foreach loop
array_walk_recursive($arr, function($v,$k) use (&$r){
$r[$k] = isset($r[$k]) ? ($r[$k]+$v) : $v;
});
Working demo :- https://3v4l.org/MMDEv
I need to flatten a PHP array but having some issues getting the desired results.
Array
(
[0] => Array
(
[case_code_id] => 1
[parent_id] => 0
[case_code] => Main A
[sub_codes] => Array
(
[0] => Array
(
[case_code_id] => 3
[parent_id] => 1
[case_code] => Sub A
[sub_codes] => Array
(
[0] => Array
(
[case_code_id] => 5
[parent_id] => 3
[case_code] => Sub Sub A
[sub_codes] => Array
(
)
)
)
)
[1] => Array
(
[case_code_id] => 4
[parent_id] => 1
[case_code] => Sub B
[sub_codes] => Array
(
)
)
)
)
[1] => Array
(
[case_code_id] => 2
[parent_id] => 0
[case_code] => Main B
[sub_codes] => Array
(
)
)
)
But I would like to convert this to the following:
Array
(
[0] => Array
(
[case_code_id] => 1
[parent_id] => 0
[case_code] => Main A
)
[1] => Array
(
[case_code_id] => 3
[parent_id] => 1
[case_code] => Sub A
)
[2] => Array
(
[case_code_id] => 5
[parent_id] => 3
[case_code] => Sub Sub A
)
[3] => Array
(
[case_code_id] => 4
[parent_id] => 1
[case_code] => Sub B
)
[4] => Array
(
[case_code_id] => 2
[parent_id] => 0
[case_code] => Main B
[sub_codes] => Array
)
I have tried several loops but nothing returns the full array.
Here is what I have for my loop:
public function array_flatten($array,$list=array()){
for ($i=0;$i<count($array);$i++) {
$results[] = array(
'case_code_id'=>$array[$i]['case_code_id'],
'case_code'=>$array[$i]['case_code'],
'parent_id'=>$array[$i]['parent_id']
);
if (count($array[$i]['sub_codes']) > 0) {
$this->array_flatten($array[$i]['sub_codes'],$results);
} else {
$results[] = $array[$i];
}
}
return $results;
}
And I'm calling it like this: ($multi contains the multidimensional array)
$flat = $this->array_flatten($multi);
The variable $multi is created from this function:
public function build_case_code_tree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = $this->build_case_code_tree($elements, $element['case_code_id']);
$element['sub_codes'] = $children;
$branch[] = $element;
}
}
return $branch;
}
Any thoughts?
function array_flatten($a, $flat = []) {
$entry = [];
foreach ($a as $key => $el) {
if (is_array($el)) {
$flat = array_flatten($el, $flat);
} else {
$entry[$key] = $el;
}
}
if (!empty($entry)) {
$flat[] = $entry;
}
return $flat;
}
print_r(array_flatten($multi));
You're not using $list anywhere in the code, and nothing is passed by reference.
You're close, but your function should use $list in the place of $results, and it should receive $list by reference and modifying it in place instead of returning it.
Something like this (untested though):
function array_flatten($array,&$list=array()){
for ($i=0;$i<count($array);$i++) {
$list[] = array(
'case_code_id'=>$array[$i]['case_code_id'],
'case_code'=>$array[$i]['case_code'],
'parent_id'=>$array[$i]['parent_id']
);
if (count($array[$i]['sub_codes']) > 0) {
$this->array_flatten($array[$i]['sub_codes'],$list);
} else {
$list[] = $array[$i];
}
}
}
And calling it like this:
$flat = Array();
$this->array_flatten($multi, $flat);
// Result is inside $flat now
I have an array like this and it can contain multiple values:
Array
(
[rpiid] => Array
(
[1] => 86
)
[sensor_id] => Array
(
[1] => 1
)
[when] => Array
(
[1] => 2014-02-24
)
[val] => Array
(
[1] => 000
)
[train] => Array
(
[1] => True
)
[valid] => Array
(
[1] => False
)
[button] => update
)
Of course, here there is only the number 1 each time but sometimes I have 0, 1, 2 and a value associated. This is because I get this from a GET from multiple forms.
How can I transform this array into
Array
(
[0] => Array
(
[rpiid] => 86
[sensor_id] => 1
...
Thanks,
John.
if your array is $get
$newArray = Array();
foreach($get as $secondKey => $innerArray){
foreach($value as $topKey => $value) {
$newArray[$topKey][$secondKey] = $value;
}
}
This should work
$new_array = array();
foreach($first_array as $value => $key){
$new_array[$key] = $value[1];
}
Sure you can, take a look at this small example:
$a = [ 'rpid' => [1], 'cpid' => [2,2] ];
$nodes = [];
foreach($a as $node => $array) {
foreach($array as $index => $value) {
if(empty($nodes[$index]))
$nodes[$index] = [];
$nodes[$index][$node] = $value;
}
}
print_r($nodes):
Array
(
[0] => Array
(
[rpid] => 1
[cpid] => 2
)
[1] => Array
(
[cpid] => 2
)
)
The 3D assoc. array looks like below.
Array
(
[COL] => Array
(
[0] => Array
(
[emp_num] => 1000001
[user_name] => Test User
[amount] => 775.00
[name] => COL
)
[1] => Array
(
[emp_num] => 26
[user_name] => John Doe
[amount] => 555.00
[name] => COL
)
)
[RA. 20%] => Array
(
[0] => Array
(
[emp_num] => 1000001
[user_name] => Test User
[amount] => 110.00
[name] => RA. 20%
)
)
[BS] => Array
(
[0] => Array
(
[emp_num] => 1000001
[user_name] => Test User
[amount] => 444.00
[name] => BS
)
)
)
I want to remove the the last key=>value pair of each inner most array. (want to remove the key value pair that has [name] for the key)
The result should look like the array below.
Array
(
[COL] => Array
(
[0] => Array
(
[emp_num] => 1000001
[user_name] => Test User
[amount] => 775.00
)
[1] => Array
(
[emp_num] => 26
[user_name] => John Doe
[amount] => 555.00
)
)
[RA. 20%] => Array
(
[0] => Array
(
[emp_num] => 1000001
[user_name] => Test User
[amount] => 110.00
)
)
[BS] => Array
(
[0] => Array
(
[emp_num] => 1000001
[user_name] => Test User
[amount] => 444.00
)
)
)
I wrote a function to do this.
<!-- language: php -->
function remove_name_from_psa($psa_array){
foreach( $psa_array as $key=>$value ) {
foreach( $value as $key2=>$value2 ){
foreach( $value2 as $key3=>$value3 ){
if( $key3 != 'name') {
$psa_name_removed[$key][$value[$key2][$value2[$key3]]] = $value3;
}
}
}
}
return $psa_name_removed;
}
The returned array is this, which is obviously not what I need.
Array ( [COST OF LIVING] => Array
( [] => 555.00 )
[RENT ALLOW. 20%] => Array
( [] => 110.00 )
[BASIC SALARY] => Array
( [] => 444.00 )
)
And there are lots of undefined offset and undefined index notices.
$psa_name_removed[$key][$value[$key2][$value2[$key3]]] = $value3; //is this the line I am doing the mistake? Or is the whole method a mistake? :-P
How can I get this to work? Can anyone help?
Thank You!
function remove_name_from_psa($psa_array){
foreach( $psa_array as $key => $value ) {
foreach( $value as $key2 => $value2 ){
unset( $psa_array[$key][$key2]['name'] );
}
}
return $psa_array;
}
Wee, functional solution!
$array = array_map(function ($i) {
return array_map(function ($j) {
return array_diff_key($j, array_flip(array('name')));
}, $i);
}, $array);
More traditional solution:
foreach ($array as &$i) {
foreach ($i as &$j) {
unset($j['name']);
}
}
Note the & in as &$i. Use this reference to modify the item.
foreach($array as &$foo){
foreach($foo as &$bar){
unset($bar['name']);
}
}
To truly unset the last element in a 3D array your would do this:
$data = array(
array(
array(1, 2, 3),
),
);
foreach ($data as $i1 => $j1) {
foreach ($j1 as $i2 => $j2) {
end($j2);
unset($data[$i1][$i2][key($j2)]);
}
}
var_dump($data);
See it in action here:
http://codepad.viper-7.com/CbgnVf
function remove_name_from_psa( $psa_array ){
foreach( $psa_array as $key => $value ) {
foreach( $value as $key2 => $value2 ) {
array_pop( $psa_array[$key][$key2] );
}
}
return $psa_array;
}
I have tried to make a function that iterates through the following array to flatten it and add parent id to children, where applicable. I just can't make it work, so I hope that anyone here has an idea of what to do:
Here's the starting point:
Array
(
[0] => Array (
[id] => 1
[children] => array (
[id] => 2
[children] => Array (
[0] => Array (
[id] => 3
)
)
)
)
The expected result :
Array (
[0] => array (
[id] => 1
)
[1] => array (
[id] => 2
)
[2] => array (
[id] => 3,
[parent] => 2
)
)
Hope that anyone can point me in the right direction. Thanks a lot!
Solution (Thanks to Oli!):
$output = array();
function dejigg($in) {
global $output;
if (!isset($in['children'])) {
$in['children'] = array();
}
$kids = $in['children'] or array();
unset($in['children']);
if (!isset($in['parent'])) {
$in['parent'] = 0; // Not neccessary but makes the top node's parent 0.
}
$output[] = $in;
foreach ($kids as $child) {
$child['parent'] = $in['id'];
dejigg($child); // recurse
}
return $output;
}
foreach ($array as $parent) {
$output[] = dejigg($parent);
}
$array = $output;
print("<pre>".print_r($array,true)."</pre>");
I've tested it this time. This does work!
$input = array( array('id' => 1, 'children'=>array( array('id'=>2, 'children'=>array( array('id'=>3) ) ) ) ) );
$output = [];
function dejigg($in) {
global $output;
$kids = $in['children'] or array();
unset($in['children']);
$output[] = $in;
foreach ($kids as $child) {
$child['parent'] = $in['id'];
dejigg($child); // recurse
}
}
foreach ($input as $parent)
dejigg($parent);
print_r($output);
And it returns:
Array
(
[0] => Array
(
[id] => 1
)
[1] => Array
(
[id] => 2
[parent] => 1
)
[2] => Array
(
[id] => 3
[parent] => 2
)
)