Build child/parent from nested array - php

i have the following array:
$array[] = array('person'=>'1','name'=>'john','children'=>array(array('person'=>'11','name'=>'frank'),array('person'=>'12','name'=>'billie'),array('person'=>'13','name'=>'will')));
$array[] = array('person'=>'11','name'=>'frank','children'=>array(array('person'=>'111','name'=>'jack'),array('person'=>'112','name'=>'jamie')));
$array[] = array('person'=>'12','name'=>'billie','children'=>array(array('person'=>'121','name'=>'melanie'),array('person'=>'122','name'=>'fran'),array('person'=>'123','name'=>'monica')));
$array[] = array('person'=>'13','name'=>'will');
$array[] = array('person'=>'111','name'=>'jack');
$array[] = array('person'=>'112','name'=>'jamie');
$array[] = array('person'=>'121','name'=>'melanie');
$array[] = array('person'=>'122','name'=>'fran');
$array[] = array('person'=>'123','name'=>'monica','children'=>array(array('person'=>'1231','name'=>'marcus'),array('person'=>'1232','name'=>'fiona')));
$array[] = array('person'=>'1231','name'=>'marcus');
$array[] = array('person'=>'1232','name'=>'fiona');
I need it to be reduced to a simple key/value array, with "child=>parent", e.g.:
array('frank'=>'john');
array('billie'=>'john');
...
array('marcus'=>'monica');
I tried with recursive function but with no luck, this is quite a brainer to me:
function buildTree($inputArray, $nameToCheck){
$arrayFinal = array();
foreach($inputArray as $data){
if($data['name'] == $nameToCheck){
if (is_array($data['children'])){
foreach($data['children'] as $childrenName){
$name = $childrenName['name'];
$arrayFinal[$name] = buildTree($inputArray, $name);
}
}
}
}
return $arrayFinal;
}
any idea ?

Is this what you want? example
<?php
$array[] = array(
'person' => '1', 'name' => 'john',
'children' => array(
array('person' => '11', 'name' => 'frank'),
array('person' => '12', 'name' => 'billie'),
array('person' => '13', 'name' => 'will')
)
);
$array[] = array(
'person' => '11', 'name' => 'frank',
'children' => array(
array('person' => '111', 'name' => 'jack'),
array('person' => '112', 'name' => 'jamie')
)
);
$array[] = array(
'person' => '12', 'name' => 'billie',
'children' => array(
array('person' => '121', 'name' => 'melanie'),
array('person' => '122', 'name' => 'fran'),
array('person' => '123', 'name' => 'monica')
)
);
$array[] = array('person' => '13', 'name' => 'will');
$array[] = array('person' => '111', 'name' => 'jack');
$array[] = array('person' => '112', 'name' => 'jamie');
$array[] = array('person' => '121', 'name' => 'melanie');
$array[] = array('person' => '122', 'name' => 'fran');
$array[] = array(
'person' => '123', 'name' => 'monica',
'children' => array(
array('person' => '1231', 'name' => 'marcus'),
array('person' => '1232', 'name' => 'fiona')
)
);
$array[] = array('person' => '1231', 'name' => 'marcus');
$array[] = array('person' => '1232', 'name' => 'fiona');
$output = [];
foreach ($array as $parent) {
if (isset($parent["children"])) {
foreach ($parent["children"] as $child) {
$output[] = array($child["name"] => $parent["name"]);
}
}
}
print "<pre>";
print_r($output);
print "</pre>";

Related

Create Array From Key

Thank you in advance. Is there any way to create a multidimensional array from key names.
$array = array(
'brand/name' => 'BRAND_NAME',
'brand/model' => 'MODEL_NO',
'brand/inv/qty' => '20',
'brand/inv/cost' => '30',
'wh' => 'NY',
'brand/inv/sales' => '40'
);
Transform to this array.
$array = array(
'brand' => array(
'name' => 'BRAND_NAME',
'model' => 'MODEL_NO',
'inv' => array(
'qty' => 20,
'cost' => 30,
'sales' => 40,
)
),
'wh' => 'NY'
);
Thank you !
Try my code (I used the reference operator "&" to get the successive inner arrays):
Input array:
$array = array(
'brand/name' => 'BRAND_NAME',
'brand/model' => 'MODEL_NO',
'brand/inv/qty' => '20',
'brand/inv/cost' => '30',
'wh' => 'NY',
'brand/inv/sales' => '40'
);
php code:
<?php
$resultArray = array();
foreach($array as $path => $element) {
$pathArray = explode("/", $path);
$auxRef = &$resultArray;
foreach($pathArray as $pathPart) {
if(! array_key_exists($pathPart, $auxRef)) {
$auxRef[$pathPart] = array();
}
$auxRef = &$auxRef[$pathPart];
}
$auxRef = $element;
unset($auxRef);
}
?>
Result array:
array ( 'brand' => array ( 'name' => 'BRAND_NAME', 'model' => 'MODEL_NO', 'inv' => array ( 'qty' => '20', 'cost' => '30', 'sales' => '40', ), ), 'wh' => 'NY', )

PHP compare array and return the different

I have two arrays with data in them and I need to compare the two and return the array that are not matched.
I have two arrays that both look like this:
$arr1 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
);
$arr2 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
);
i would like comparing the array by name,age and country and return me the array that are not matched.
my code so far:
$intersect = array_uintersect($arr1, $arr2, 'compareDeepValue');
echo "<pre>", print_r($intersect);
function compareDeepValue($val1, $val2)
{
return strcmp($val1['age'], $val2['age']);
return strcmp($val1['country'], $val2['country']);
return strcmp($val1['name'], $val2['name']);
}
The code above return the array that are matched. How can i changed the code in order to get the array that are not matched?
EXPECTED OUTPUT:
Array
(
[0] => Array
(
[name] => James
[age] => 21
[country] => spain
)
)
The code mentioned by someone in answers will work, but it's manual labor :)
You could use existing functions to do the job for you. For computing the difference between arrays, you should use array_udiff function (or functions related).
You should write function to compare arrays, and use it to compute the difference, like this:
<?php
$arr1 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
);
$arr2 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
);
// this function checks if 2 arrays with keys and scalar values are the same
function array_same_check($deepArr1, $deepArr2) {
//check if arrays are the same
$diffArr = array_diff_assoc($deepArr1, $deepArr2);
//if $diffArr has 0 elements - arrays are the same
if (count($diffArr) === 0) {
return 0;
}
// arrays are not the same - return arbitratry 1 or -1
return 1;
}
// now let's compare $arr1 and $arr2 you have
// (meaning: compare the difference between arrays containing arrays) - we use function above
$differing = array_udiff ($arr1, $arr2, 'array_same_check');
print_r($differing);
I copied this code to PHPFiddle and it seems to work as expected.
Your Arrays:
$arr1 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
);
$arr2 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
);
foreach($arr1 as $key=>$arr)
{
$bool = true;
$ar1 = $arr;
$ar2 = $arr2[$key];
foreach($ar1 as $ky=>$val)
{
if($val != $ar2[$ky])
{
$bool = false;
break;
}
}
if(!$bool)
{
echo "Unmatched Arrays: \r\n";
print_r($ar1); echo " in Main Array 1 & \r\n";
print_r($ar2); echo " in Main Array 2. \r\n";
}
}
try this one
$arr1 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
);
$arr2 = array(
array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
);
$tmpArray = array();
foreach($arr1 as $data1) {
$duplicate = false;
foreach($arr2 as $data2) {
if($data1['name'] === $data2['name'] && $data1['age'] === $data2['age'] && $data1['country'] === $data2['country']) $duplicate = true;
}
if($duplicate === false) $tmpArray[] = $data1;
}
echo "<pre>", print_r($tmpArray);
$intersect = array_uintersect($arr1, $arr2, 'compareDeepValue');
print_r($intersect);
// add this and it will return the missing array.
print_r(array_diff_key($arr1, $intersect));
function compareDeepValue($val1, $val2)
{
return strcmp($val1['age'], $val2['age']);
return strcmp($val1['country'], $val2['country']);
return strcmp($val1['name'], $val2['name']);
}
I would like to give you another possible solution. I've checked the code and it seems to fit your needs.
/** #var array $arr1 */
$arr1 = array(
array(
'name' => 'Alan',
'age' => '34',
'country' => 'usa'
),
array(
'name' => 'James',
'age' => '24',
'country' => 'spain'
),
);
/** #var array $arr2 */
$arr2 = array(
array(
'name' => 'Alan',
'age' => '34',
'country' => 'usa'
),
array(
'name' => 'James',
'age' => '54',
'country' => 'spffain'
),
);
/** #var array $notMatched */
$notMatched = array();
/**
* #var int $index
* #var array $element
*/
foreach($arr1 as $index => $element) {
/**
* #var string $key
* #var string $value
*/
foreach($element as $key => $value) {
if($arr2[$index][$key] !== $value) {
$notMatched["arr1"] = $arr1[$index];
$notMatched["arr2"] = $arr2[$index];
}
}
}
if(!empty($notMatched)) {
echo "Unmatched arrays: \r\n";
echo "Array 1:\r\n";
print_r($notMatched["arr1"]);
echo "Array 2:\r\n";
print_r($notMatched["arr2"]);
}

Check if exists the same value in multidimensional array PHP

Let's say i have an array like this:
$array = array(
0 =>
array (
'value' => '1' ,
'name' => 'dasdfa sadfa' ),
1=> Array (
'value' => 'adresa#gmail.com' ,
'name' => 'd2' ),
21 =>
array(
'value' => 'adresa#gmail.com' ,
'name' => 'name1`' ),
23 =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
24 =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
26 =>
array(
'value' => 'ricardo.ramos#amadeus.com',
'name' => '43414 Test01'),
27 =>
array(
'value' => 'sta3no213123ct3av#yahoo.com',
'name' => 'oct oct' )
);
I want to know if exists duplicated value in array with key 'value' I know how to do this if i want a specified value but general no. The result must be an array with no duplicated values(eg:
$array = array(
0 =>
array (
'value' => '1' ,
'name' => 'dasdfa sadfa' ),
1=> Array (
'value' => 'adresa#gmail.com' ,
'name' => 'd2' ),
23 =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
26 =>
array(
'value' => 'ricardo.ramos#amadeus.com',
'name' => '43414 Test01'),
27 =>
array(
'value' => 'sta3no213123ct3av#yahoo.com',
'name' => 'oct oct' )
);`
Please help me.
This is my try
function has_dupes($array){
$dupe_array = array();
foreach($array as $val){
if(++$dupe_array[$val] > 1){
return true;
}
}
return false;
}
Try this way:
$array = array(
'0' =>
array (
'value' => '1' ,
'name' => 'dasdfa sadfa' ),
'1'=> Array (
'value' => 'adresa#gmail.com' ,
'name' => 'd2' ),
'21' =>
array(
'value' => 'adresa#gmail.com' ,
'name' => 'name1`' ),
'23' =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
'24' =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
'26' =>
array(
'value' => 'ricardo.ramos#amadeus.com',
'name' => '43414 Test01'),
'27' =>
array(
'value' => 'sta3no213123ct3av#yahoo.com',
'name' => 'oct oct' )
);
$array = array_map("unserialize", array_unique(array_map("serialize", $array)));
$result = array_unique($array);
print_r($result);
And if you want to store all unique data in one array do it like this:
//declare $array
$unique_array = array();
foreach ($array as $key => $type) {
foreach($type as $vale => $name) {
if ($vale == 'value') {
//echo $name . '<br>';
array_push($unique_array, $name);
}
}
}
$result = array_unique($unique_array);
foreach ($result as $res) {
echo $res . '<br>';
}
Try this
$values = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($values as $key => $value)
{
if ( is_array($value) )
{
$values[$key] = $value;
}
}
print_r($values);
$unique_data = array(); // the result array
$duplicate_data = array();
$seen = array();
foreach ($array as $key => $arr) {
$value = $arr['value'];
if (!isset($seen[$value])) {
$seen[$value] = '';
$unique_data[$key] = $arr;
} else {
$duplicate_data[$key] = $arr; // optional
}
}
unset($seen); // optional in function scope

Sort array and rebuild it

I have this array:
$all = array(
'meat' => Object(
'name' => 'meat',
'color' => 'red',
'class' => 'food'
),
'chicken' => Object(
'name' => 'chicken',
'color' => 'white',
'class' => 'food'
),
'apple' => Object(
'name' => 'apple',
'color' => 'green',
'class' => 'Fruit'
),
'blueberry' => Object(
'name' => 'blueberry',
'color' => 'blue',
'class' => 'Fruit'
)
);
and i want to Sort it and rebuild it to be like this:
$theright = array(
array(
'class' => 'food',
'menu' => array(
array(
'name' => 'meat',
'color' => 'red',
),
array(
'name' => 'chicken',
'color' => 'white',
)
)
),
array(
'class' => 'Fruit',
'menu' => array(
array(
'name' => 'apple',
'color' => 'green',
),
array(
'name' => 'blueberry',
'color' => 'blue',
)
)
)
);
I tried to Collect all classes in$all array then compare each value with $all array:
$classArray = array();
foreach($all as $key => $value) {
$classArray[$value->class] = array();
}
foreach($classArray as $key => $value) {
$theright[] = array('class' => $key, 'menu' => array());
}
this code get me this array:
$theright = array(
array(
'class' => 'food',
'menu' => array()
),
array(
'class' => 'Fruit',
'menu' => array()
)
);
and i stop here , how to complete it ?
You could just use the class as a key to group them together. Example:
$food = array();
// gather class
foreach($all as $item) {
if(!isset($food[$item->class])) {
$food[$item->class] = array(
'class' => $item->class,
'menu' => array(
array(
'name' => $item->name,
'color' => $item->name,
)
)
);
} else {
$food[$item->class]['menu'][] = array('name' => $item->name,'color' => $item->color,);
}
}
// simple reindex
$food = array_values($food);
There is no need for a second loop. This should do what you want.
$classMap = array();
foreach ($all as $item)
{
// check if class has been created in the class map
if ( ! array_key_exists($classMap, $item['class']))
{
$classMap[$item['class']] = array(
'class' => $item['class'],
'menu' => array()
);
}
$classMap[$item['class']]['menu'][] = array(
'name' => $item['name'],
'color' => $item['color']
);
}
Try with less loop counts (2)
$all = [];
function getSelectClassData(array &$all)
{
$finalArr = [];
while (count($all) > 1) {
$res = [];
$class = array_values($all)[0]->class;
$selectedDataArr = getSelectSimilerMenuData($all, $class);
$res['class'] = $class;
$res['menu'] = array_values($selectedDataArr);
$all = array_diff_key($all,array_flip(array_keys($selectedDataArr)));
$finalArr[] = $res;
}
return $finalArr;
}
function getSelectSimilerMenuData(array $all, $class)
{
return array_filter(
$all,
function ($e) use ($class) {
return $e->class == $class;
}
);
}
print_r(getSelectClassData($all));

Format JSON data in order to pass it correctly to the Google chart engine

Im trying to build a very easy table:
Sex %
M 40
F 60
Using php to encode an array but no graph is drawn assuming that the input data is wrong. Can you tell where is the problem?
$table = array();
$table['cols'] = array(
array('label' => 'Sesso', 'type' => 'string'),
array('label' => 'Quantita', 'type' => 'number'));
$rows = array();
$temp = array();
$temp[] = array('v' => 'M');
$temp[] = array('v' => 60);
$rows[] = array('c' => $temp);
$temp = array();
$temp[] = array('v' => 'F');
$temp[] = array('v' => 40);
$rows[] = array('c' => $temp);
$table['rows'] = $rows;
$jsonTable = json_encode($table);
What happens if you try:
$table = array(
'cols' => array(
array(
'id' => '1',
'label' => 'Sesso',
'type' => 'string'
),
array(
'id' => '2',
'label' => 'Quantita',
'type' => 'number'
)
),
'rows' => array(
array(
'c' => array(
array(
'v' => 'M',
'f' => 60
)
)
),
array(
'c' => array(
array(
'v' => 'F',
'f' => 40
)
)
)
)
);
$json = json_encode($table);
Check out Google's example in their documentation. The JSON structure you should be aiming for is:
{
"cols": [
{"id":"","label":"Topping","pattern":"","type":"string"},
{"id":"","label":"Slices","pattern":"","type":"number"}
],
"rows": [
{"c":[{"v":"Mushrooms","f":null},{"v":3,"f":null}]},
{"c":[{"v":"Onions","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Olives","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Zucchini","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Pepperoni","f":null},{"v":2,"f":null}]}
]
}
This is what i did:
$table = array(
'cols' => array(
array( 'id' => '', 'label' => 'Sesso', 'pattern' => '', 'type' => 'string' ),
array( 'id' => '', 'label' => '#', 'pattern' => '', 'type' => 'number' )
),
'rows' => array(
array( 'c' => array( array( 'v' => 'Uomini', 'f' => null ), array('v' => 60, 'f' => null) ) ),
array( 'c' => array( array( 'v' => 'Donne', 'f' => null ), array('v' => 40, 'f' => null) ) )
)
);

Categories