Nested array to flat with parent_id creating - php

I want to create flat array from nested array, like this one:
[0]=>Array(
"id"=>1,
"positions">Array(
[0]=>Array(
"id"=>2
),
[1]=>Array(
"id"=>3
"positions"=>Array(
[0]=>Array(
"id"=>4
)
)
)
to something like this:
[0]=>Array(
"id"=>1,
"parent_id"=>0
),
[1]=>Array(
"id"=>2,
"parent_id"=>1
),
[2]=>Array(
"id"=>3,
"parent_id"=>1
),
[3]=>Array(
"id"=>4,
"parent_id"=>3
)
I don't have parent_id in nested structure, so all the trick is to "ride" trough the nested array, and add 'parent_id', base on id from parent node. I know how to flat the array, but I need parent_id information.

Try below code : i hope useful it...
<?php
$array = array(array(
"id"=>1,
"positions" =>
array(
array(
"id"=>2
),
array(
"id"=>3,
"positions"=>
array(
array(
"id"=>4
)
)
)
)
));
echo "<pre>";
print_r(getArray($array));
echo "</pre>";
exit;
function getArray($array,$parent_id = 0)
{
$result = array();
foreach ($array as $value)
{
$tmp = array();
$tmp['id'] = $value['id'];
$tmp['parent_id'] = $parent_id;
$result[] = $tmp;
if(!empty($value['positions']))
{
$result= array_merge($result,getArray($value['positions'],$value['id']));
}
}
return $result;
}
?>
OUTPUT :
Array
(
[0] => Array
(
[id] => 1
[parent_id] => 0
)
[1] => Array
(
[id] => 2
[parent_id] => 1
)
[2] => Array
(
[id] => 3
[parent_id] => 1
)
[3] => Array
(
[id] => 4
[parent_id] => 3
)
)

Use this code
$result = array();
function generateArray($array,$parent=0){
foreach ($array as $key=>$val){
$tmp = array();
if(!empty($val['id'])){
$tmp['id'] = $val['id'];
$tmp['parent_id'] = $parent;
$result[] = $tmp;
}
if(!empty($val['positions'])){
$result=array_merge($result,generateArray($val['positions'],$val['id']));
}
}
return $result;
}
Your array must be of this structure
$data = array(0=>array("id"=>1,"positions"=>array(0=>array("id"=>2),1=>array("id"=>3,"positions"=>array(0=>array("id"=>4))))));
Then call the function generateArray(),
var_dump(generateArray($data));

Related

Get the unique array from an array with the lowest number

im having trouble figuring this one out, the scenario is, that there is an multidimensional array, in which there is name, id, and number in an array, what i want is to get the unique array in which array having same name should not appear, this can be done and i had done it, but i also want that the array that is returned should contain the lowest num, i hope this would help make you understand
i have
Array(
[0]=>array(
[id]=>1
[name]=>abc
[num]=>4)
[1]=>
array(
[id]=>2
[name]=>efg
[num]=>4)
[2]=>array(
[id]=>3
[name]=>abc
[num]=>2)
)
Now its a rough array representation, what i want from this is
Array(
[0]=>array(
[id]=>3
[name]=>abc
[num]=>2)
[1]=>
array(
[id]=>2
[name]=>efg
[num]=>4)
What im using:
code.php
<?php
$details = array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"9876543210"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
2 => array("id"=>"1", "name"=>"Mathew", "num"=>"784581254"),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$details = unique_multidim_array($details,'name');
?>
This function returns me
Array(
[0]=>array(
[id]=>1
[name]=>abc
[num]=4)
[1]=>
array(
[id]=>2
[name]=>efg
[num]=>4)
You can use array_reduce:
$result = array_reduce
(
$array,
function( $carry, $item )
{
if( !isset( $carry[$item['name']] ) || $item['num'] < $carry[$item['name']]['num'] )
{
$carry[$item['name']] = $item;
}
return $carry;
},
[] // This parameter (empty array) is optional in this case
);
$result = array_values( $result );
We compare each array element with constructing returned array (initially empty): if in returned array doesn't exists an item with key = $item['name'], we add it; otherwise, if current item has num value lower than corresponding returned array item, we replace this item with current item. At the end, we use array_values to remove associative keys.
Result:
Array
(
[0] => Array
(
[id] => 3
[name] => abc
[num] => 2
)
[1] => Array
(
[id] => 2
[name] => efg
[num] => 4
)
)
Read more about array_reduce
Read more about array_values
I would do this with two loops
First, group the values by name, then number
foreach ($your_array as $value) {
$names[$value['name']][$value['num']] = $value;
}
Then iterate the result of that, sort name by key (num) and append the first element to the final result.
foreach ($names as $set_of_nums) {
ksort($set_of_nums);
$result[] = reset($set_of_nums);
}
I have considered the below example.
$details = array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"123"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"235"),
2 => array("id"=>"3", "name"=>"Mike", "num"=>"5"),
3 => array("id"=>"4", "name"=>"Tom", "num"=>"256"),
4 => array("id"=>"5", "name"=>"Tom", "num"=>"500"),
5 => array("id"=>"6", "name"=>"Mike", "num"=>"7"),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$key_array = array();
foreach($array as $k=>$val) {
if (!in_array($val[$key], $key_array)) {
// storing the array with the key
$key_array[$k] = $val[$key];
$temp_array[$k] = $val;
} else{
foreach($key_array as $r=>$p){
//check for the array with the name
if($temp_array[$r]['name'] == $val['name']){
// compare the value
if($temp_array[$r]['num']>$val['num']){
// store the new array to the temp_array with same key of key_array
$temp_array[$r] = $val;
}
}
}
}
}
return $temp_array;
}
$details = unique_multidim_array($details,'name');
Output:
Array
(
[0] => Array
(
[id] => 3
[name] => Mike
[num] => 5
)
[1] => Array
(
[id] => 2
[name] => Carissa
[num] => 235
)
[3] => Array
(
[id] => 4
[name] => Tom
[num] => 256
)
)
You can sort the output array using any of the sort functions as you desire.

create new array merge

I have an array:
array(
[0] => Array
(
[d1] => Array
(
................
)
[d2] => Array
(
................
)
)
[1] => Array
(
[d1] => Array
(
................
)
[d2] => Array
(
................
)
)
)
How to create a new array to merge it, so only d1 and d2, remove the index 0 and 1.
For PHP > 5.5.0 you can simply use array_column like as
$result['d1'] = call_user_func_array('array_merge',array_column($your_array,'d1'));
$result['d2'] = call_user_func_array('array_merge',array_column($your_array,'d2'));
print_r($result);
Demo
Let us say your array name is $a, so we can have:
$result = [];
$result['d1'] = [];
$result['d2'] = [];
foreach ($a as $v) {
$result['d1'] = array_merge($result['d1'], $v['d1'])
$result['d2'] = array_merge($result['d2'], $v['d2'])
}
Now you have what you want in $result.
here is your solution visit here
Suppose your array $menus and after filter new array will be $filteredMenu . Your final result $filteredMenu
<?php
$menus = array(
0 =>array(
"d1" => array (
"id"=> "----",
),
"d2" => array (
"id"=> "----",
)
),
1 =>array(
"d1" => array (
"id"=> "----",
),
"d2" => array (
"id"=> "----",
)
)
);
$filteredMenu = [];
$filteredMenu['d1'] = [];
$filteredMenu['d2'] = [];
foreach ($menus as $item) {
$filteredMenu['d1'] = array_merge($filteredMenu['d1'], $item['d1']);
$filteredMenu['d2'] = array_merge($filteredMenu['d2'], $item['d2']);
}
print_r($filteredMenu);
?>

select data from array that matches condition in another array in php

i have 2 arrays i want to display the final array as what are the array element in $displayArray only be displayed from the $firstArray
$firstArray = Array
(
[0] => Array
(
[Dis_id] => Dl-Dis1
[Dis_Desc] => Discount
[Dis_Per] => 7.500
[Dis_val] => 26.25
)
[1] => Array
(
[Dis_id] => Dl-Dis2
[Dis_Desc] => Discount
[Dis_Per] => 2.500
[Dis_val] => 8.13
)
)
$displayArray = Array
(
[0] => Array
(
[0] => Dis_id
[1] => Dis_val
)
)
i want the final output will be
$resultArray = Array
(
[0] => Array
(
[Dis_id] => Dl-Dis1
[Dis_val] => 26.25
)
[1] => Array
(
[Dis_id] => Dl-Dis2
[Dis_val] => 8.13
)
)
Both the $firstArray and the $DisplayArray are dynamic but the $displayArray should be one.
i dont know how to do give me any suggestion
First up, if $displayArray will never have more than one array, the answer is pretty simple. Start by popping the inner array, to get to the actual keys you will need:
$displayArray = array_pop($displayArray);//get keys
$resultArray = array();//this is the output array
foreach ($firstArray as $data)
{
$item = array();
foreach ($displayArray as $key)
$item[$key] = isset($data[$key]) ? $data[$key] : null;//make sure the key exists!
$resultArray[] = $item;
}
var_dump($resultArray);
This gives you what you need.
However, if $displayArray contains more than 1 sub-array, you'll need an additional loop
$resultArray = array();
foreach ($displayArray as $k => $keys)
{
$resultArray[$k] = array();//array for this particular sub-array
foreach ($firstArray as $data)
{
$item = array();
foreach ($keys as $key)
$item[$key] = isset($data[$key]) ? $data[$key] : null;
$resultArray[$k][] = $item;//add data-item
}
}
var_dump($resultArray);
the latter version can handle a display array like:
$displayArray = array(
array(
'Dis_id',
'Dis_val'
),
array(
'Dis_id',
'Dis_desc'
)
);
And it'll churn out a $resultArray that looks like this:
array(
array(
array(
'Dis_id' => 'foo',
'Dis_val' => 123
)
),
array(
array(
'Dis_id' => 'foo',
'Dis_desc' => 'foobar'
)
)
)
Job done

PHP Counting inside an Array

I want to create a list where if its already in the array to add to the value +1.
Current Output
[1] => Array
(
[source] => 397
[value] => 1
)
[2] => Array
(
[source] => 397
[value] => 1
)
[3] => Array
(
[source] => 1314
[value] => 1
)
What I want to Achieve
[1] => Array
(
[source] => 397
[value] => 2
)
[2] => Array
(
[source] => 1314
[value] => 1
)
My current dulled down PHP
foreach ($submissions as $timefix) {
//Start countng
$data = array(
'source' => $timefix['parent']['id'],
'value' => '1'
);
$dataJson[] = $data;
}
print_r($dataJson);
Simply use an associated array:
$dataJson = array();
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (!isset($dataJson[$id])) {
$dataJson[$id] = array('source' => $id, 'value' => 1);
} else {
$dataJson[$id]['value']++;
}
}
$dataJson = array_values($dataJson); // reset the keys - you don't nessesarily need this
This is not exactly your desired output, as the array keys are not preserved, but if it suits you, you could use the item ID as the array key. This would simplify your code to the point of not needing to loop through the already available results:
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (array_key_exists($id, $dataJson)) {
$dataJson[$id]["value"]++;
} else {
$dataJson[$id] = [
"source" => $id,
"value" => 1
];
}
}
print_r($dataJson);
You should simplify this for yourself. Something like:
<?
$res = Array();
foreach ($original as $item) {
if (!isset($res[$item['source']])) $res[$item['source']] = $item['value'];
else $res[$item['source']] += $item['value'];
}
?>
After this, you will have array $res which will be something like:
Array(
[397] => 2,
[1314] => 1
)
Then, if you really need the format specified, you can use something like:
<?
$final = Array();
foreach ($res as $source=>$value) $final[] = Array(
'source' => $source,
'value' => $value
);
?>
This code will do the counting and produce a $new array as described in your example.
$data = array(
array('source' => 397, 'value' => 1),
array('source' => 397, 'value' => 1),
array('source' => 1314, 'value' => 1),
);
$new = array();
foreach ($data as $item)
{
$source = $item['source'];
if (isset($new[$source]))
$new[$source]['value'] += $item['value'];
else
$new[$source] = $item;
}
$new = array_values($new);
PHP has a function called array_count_values for that. May be you can use it
Example:
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Output:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

Group rows by one column, only create deeper subarrays when multiple rows in group

I have a multi-dimensional array like this:
Array
(
[0] => Array
(
[id] => 1
[email_id] => ok#gmail.com
[password] => test
)
[1] => Array
(
[id] => 2
[email_id] => check#gmail.com
[password] => test
)
[2] => Array
(
[id] => 3
[email_id] => an#gmail.com
[password] => pass
)
)
In the above array, password value is the same in two different rows. I need to merge the arrays which have duplicate values to get the following output:
Array
(
[0] => Array
(
[0] => Array
(
[id] => 1
[email_id] => ok#gmail.com
[password] => test
)
[1] => Array
(
[id] => 2
[email_id] => check#gmail.com
[password] => test
)
)
[1] => Array
(
[id] => 3
[email_id] => an#gmail.com
[password] => pass
)
)
How to do this? I've tried array_merge() & foreach() loops, but I can't get this output.
Try,
$arr = array( array('id'=>1, 'email_id'=>'ok#gmail.com', 'password'=>'test'),
array('id'=>2, 'email_id'=>'check#gmail.com', 'password'=>'test'),
array('id'=>3, 'email_id'=>'an#gmail.com', 'password'=>'pass'));
$new_arr = array();
foreach($arr as $k => $v) {
if( is_array($arr[$k+1]) && $arr[$k]['password'] === $arr[$k + 1]['password'] )
$new_arr[] = array($arr[$k], $arr[$k+1]);
else if( in_array_recursive($arr[$k]['password'], $new_arr) === FALSE )
$new_arr[] = $v;
}
function in_array_recursive( $val, $arr) {
foreach( $arr as $v ) {
foreach($v as $m) {
if( in_array($val, $m ) )
return TRUE;
}
}
return FALSE;
}
print_r($new_arr);
Demo
You only want to create more depth in your output array if there is more than one entry in the group. I personally wouldn't want that kind of variability in a data structure because the code that will print the data will need to go to extra trouble to handle associative rows of data that might be on different levels.
Anyhow, here's how I would do it with one loop...
Foreach Loop Code: (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($result[$row['password']])) {
$result[$row['password']] = $row; // save shallow
} else {
if (isset($result[$row['password']]['id'])) { // if not deep
$result[$row['password']] = [$result[$row['password']]]; // make original deeper
}
$result[$row['password']][] = $row; // save deep
}
}
var_export(array_values($result)); // print without temporary keys
Functional Code: (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row['password']])) {
$result[$row['password']] = $row;
} else {
if (isset($result[$row['password']]['id'])) {
$result[$row['password']] = [$result[$row['password']]];
}
$result[$row['password']][] = $row;
}
return $result;
},
[]
)
)
);

Categories