Converting table-like array to a tree-like array - php

Consider the following example:
function tableToTree($array, $parents)
{
$result = [];
$p = $parents;
foreach ($array as $k => $row) {
$result[$row[$p[0]]][$row[$p[1]]]= $row[$p[2]]; // **
}
return $result;
}
$foo = [
['x' => 'a', 'y' => 'n','z'=>'AA'],
['x' => 'a', 'y' => 'm','z'=>'BB'],
['x' => 'b', 'y' => 'v','z'=>'CC'],
['x' => 'b', 'y' => 'w','z'=>'DD'],
];
print_r(tableToTree($foo, ['x', 'y','z']));
Which yields:
Array
(
[a] => Array
(
[n] => AA
[m] => BB
)
[b] => Array
(
[v] => CC
[w] => DD
)
)
The above code only works when there are only two parents. How to rewrite the line denoted by ** in a way that it work with arbitrary number of parents.

function tableToTree($array, $parent)
{
$result = array();
foreach ($array as $row) {
$r = &$result; // pointer to result
$p = $parent; // temporary copy of parents
while(count($p) > 2) { // until last key and value
$i = array_shift($p); // next key
if(!isset($r[$row[$i]])) $r[$row[$i]] = null; // add level
$r = &$r[$row[$i]]; // shift pointer to new level
}
$r[$row[array_shift($p)]] = $row[array_shift($p)]; // set value
}
return $result;
}
$foo = array(
array('N' => 2, 'x' => 'a', 'y' => 'n','z'=>'AA'),
array('N' => 1, 'x' => 'a', 'y' => 'm','z'=>'BB'),
array('N' => 2, 'x' => 'b', 'y' => 'v','z'=>'CC'),
array('N' => 1, 'x' => 'b', 'y' => 'w','z'=>'DD'),
array('N' => 1, 'x' => 'c', 'y' => 'w','z'=>'DD'));
print_r(tableToTree($foo, array('N','x', 'y','z')));
result
array (
2 => array (
'a' => array ( 'n' => 'AA',),
'b' => array ( 'v' => 'CC',),
),
1 => array (
'a' => array ( 'm' => 'BB', ),
'b' => array ( 'w' => 'DD', ),
'c' => array ( 'w' => 'DD', ),
),
)

Related

PHP producing a multidimensional associative array in desired format

I am trying to wrangle data into a desired format. Basically, I have a list in which a subset of the entities can have multiple values and need to be grouped and iterated over within the list.
Given the following example:
$entities = [
0 => ['name' => 'a', 'type' => 'single'],
1 => ['name' => 'b', 'type' => 'single'],
2 => ['name' => 'c', 'type' => 'grouped'],
3 => ['name' => 'd', 'type' => 'grouped'],
4 => ['name' => 'e', 'type' => 'single'],
];
foreach ($entities as $entityKey => $entity) {
if ($entity['type'] == 'single') {
$array[] = ['name' => $entity['name']];
}
if ($entity['type'] == 'grouped') {
// arbitrary number of items
$items = [0 => 'apple', 1 => 'orange', 2 => 'banana'];
foreach ($items as $itemKey => $item) {
$array[] = ['name' => $entity['name']];
}
}
}
print_r($array);
How can I produce output: a, b, c, d, c, d, c, d, e, such that the entities of type 'grouped' are paired and iterated over before he next entity is inserted into the array. Specifically:
Array
(
[0] => Array
(
[name] => a
)
[1] => Array
(
[name] => b
)
[2] => Array
(
[name] => c
)
[3] => Array
(
[name] => d
)
[4] => Array
(
[name] => c
)
[5] => Array
(
[name] => d
)
[6] => Array
(
[name] => c
)
[7] => Array
(
[name] => d
)
[8] => Array
(
[name] => e
)
)
here is a working solution for you.
$entities = [
0 => ['name' => 'a', 'type' => 'single'],
1 => ['name' => 'b', 'type' => 'single'],
2 => ['name' => 'c', 'type' => 'grouped'],
3 => ['name' => 'd', 'type' => 'grouped'],
4 => ['name' => 'e', 'type' => 'single'],
];
$grouped = [];
foreach($entities as $entity){
if($entity['type'] == 'grouped'){
$grouped[] = $entity['name'];
}
}
$f = 0;
foreach ($entities as $entity) {
if ($entity['type'] == 'single') {
$array[] = ['name' => $entity['name']];
}
if ($entity['type'] == 'grouped') {
$items = [0 => 'apple', 1 => 'orange', 2 => 'banana'];
for($i = 0; $i < count($items); $i++) {
foreach($grouped as $grouped_item){
if($f < count($items)*2){
$array[] = ['name' => $grouped_item];
}
$f++;
}
}
}
}
print_r($array);

Manage Php arrays

I am new in php.I have learn almost all things in php.I am developing sample application in php. In my application I have two arrays and it looks like:
Array
(
[0] => 1800
[5] => 1500
[6] => 4545
)
Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
[5] => f
[6] => g
)
I want output like:
Array
(
[0] => Array
(
[a] => 1800
)
[1] => Array
(
[b] => 0
)
[2] => Array
(
[c] => 0
)
[3] => Array
(
[d] => 0
)
[4] => Array
(
[e] => 0
)
[5] => Array
(
[f] => 1500
)
[6] => Array
(
[g] => 4545
)
)
Please help.
Found solution for your question.
<?php
$arr1 = array(
'0' => '1800',
'5' => '1500',
'6' => '4545'
);
$arr2 = array(
'0' => 'a',
'1' => 'b',
'2' => 'c',
'3' => 'd',
'4' => 'e',
'5' => 'f',
'6' => 'g',
);
$arr3 = array();
foreach($arr2 as $key => $value){
if(!empty($arr1[$key])){
$arr3[$key][$value] = $arr1[$key];
}
else{
$arr3[$key][$value] = 0;
}
}
print '<pre>';
print_r($arr3);
print'</pre>';
?>
$arr1 = array(0 => 1800, 5 => 1500, 6 => 4545,);
$arr2 = array('a', 'b', 'c', 'd', 'e', 'f', 'g',);
$arrNeeded = array();
foreach ($arr2 AS $k => $v) {
$arrNeeded[$k] = array($v => isset($arr1[$k]) ? $arr1[$k] : 0);
}
echo '<pre>' . print_r($arrNeeded, true) . '</pre>';
Please try with below code
$arr1 = array( 0 => 1800 ,5 => 1500 ,6=> 4545 );
$arr2 = array( 0 => 'a' ,1 => 'b', 2=> 'c',3 => 'd' ,4 => 'e' ,5 => 'f' ,6 => 'g' );
$newarr = "";
if(count($arr2) >0){
foreach($arr2 as $key2 => $val2){
$newVal = isset($arr1[$key2])?$arr1[$key2] : 0;
$newarr[$key2] = array($val2 => $newVal);
}
}
echo "<pre>";
print_r($newarr);
This might help you
<?php
$array1 = Array( "0"=>1800,"5" => 1500, "6" => 4545 ) ;
$array2 = Array( "0" => 'a', '1' => 'b', '2' => 'c', '3' => 'd', '4' => 'e', '5' => 'f', '6' => 'g' );
$resultArray = array();
foreach ($array2 as $key2 => $value2 ) {
$found = false;
foreach ($array1 as $key1 => $value1) {
if($key1 == $key2){
$resultArray[$value2] = $value1;
$found = true;
continue;
}
if(!$found)
{
$resultArray[$value2] = 0;
}
}
}
print_r($resultArray);
?>

Array remapping - Can I do this better?

for starters I have the following array objects (id, foo and bar are a result of a database query and should be addressed as object variables ->id)
array([0] => array([id] => 1, [foo] => 'a'), [1] => array([id] => 2, [foo] => 'b')
and
array([0] => array([id] => 1, [bar] => 'b'), [1] => array([id] => 2, [bar] => 'a')
I want to create one new array with the id column as key
array([1] => array([foo] => 'a', [bar] => 'b'), [2] => array([foo] => 'b', [bar] => 'a')
I used the following lines of code to create the desired array:
foreach($array1 as $row1) {
$newArray1[$row1->id] = $row1;
}
foreach($array2 as $row2) {
$newArray2[$row2->id] = $row2;
}
foreach($array2 as $key => row3) { //array 2 is always longer or equal to array 1
$result[$key]['bar'] = $newArray2[$key]->bar;
if (isset($newArray1[$key])) {
$result[$key]['foo'] = $newArray1[$key]->foo;
} else {
$result[$key]['bar'] = 0;
}
}
I think this could be done a lot easier. Is this the case, if so, how?
If I understood you need to merge two arrays using as index the 'id' field, which is equal to both ones.
I would do this:
$newarray = array();
for($i=0;$i<count($array1);$i++)
$newarray[$array1[$i]["id"]] = array($array1[$i]["foo"], $array2[$i]["bar"]);
instead of creating new array you can do this:
$arr1=array('0' => array('id' => 1, 'foo' => 'a'), '1' => array('id' => 2, 'foo' => 'b'));
$arr2=array('0' => array('id' => 1, 'bar' => 'b'), '1' => array('id' => 2, 'bar' => 'a'));
for($i=0;$i<count($arr1);$i++){
$arr1[$i] = array("foo"=>$arr1[$i]["foo"], "bar"=>$arr2[$i]["bar"]);
}
print_r($arr1);

Searching in a multi-dimensional array (PHP)

I'm having a problem lately that's driving me crazy. I have a multi-dimensional array like this:
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
)
'2' => array(
'id' => '3',
'name' => 'test',
'cat' => array(
'a' => '50',
'b' => '40',
'c' => '90'
),
'canvas' => '1'
)
)
);
And i want to search on it using a function like this: search('canvas = 1');
That would return all the arrays, child of db, that have a key canvas with the value of 1. Or, for example:
search('a = 15');
Would return all arrays that have a key, child of cat, named a and with a value of 15.
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
)
);
//checks if array $array contains element with $searchKey key, and $searchVal value
function arrayContains($array, $searchVal, $searchKey) {
if (!is_array($array))
return false;
foreach ($array as $key => $value) {
if ($key === $searchKey && $searchVal === $value)
return true;
if (is_array($value) && arrayContains($value, $searchVal, $searchKey))
return true;
}
return false;
}
function search($a, $search) {
list($searchKey, $searchVal) = explode('=', $search);
$result = array();
foreach($a as $val) {
if (arrayContains($val, $searchVal, $searchKey))
$result[] = $val;
}
return $result;
}
print_r(search($a['db'], "a=15"));
print_r(search($a['db'], "canvas=1"));
Which produces this output(outputs sub-arrays of $a['db'] which contain searched key=>value pair):
Array
(
[0] => Array
(
[id] => 1
[name] => test
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
[1] => Array
(
[id] => 2
[name] => test2
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
)
Array
(
[0] => Array
(
[id] => 3
[name] => test
[cat] => Array
(
[a] => 50
[b] => 40
[c] => 90
)
[canvas] => 1
)
)
Just check the below link if this can help you -
http://php.net/manual/en/function.array-search.php
It contains detailed documentation of php function array_search() and various user codes for searching in multi-dimensional array along with user reviews.
function search($array, $canvas)
{
$result = array();
foreach ($array as $k1 => $v1) {
foreach ($v1 as $k2 => $v2) {
if ($v2['canvas'] == $canvas) {
$result[] = $array[$k1][$k2];
}
}
}
return $result;
}
// $a = your array
print_r(search($a, 1));

Php Multidimensional Array

I have below multidimensional array
$testarray=Array
(
1 => Array
(
0 => 'A',
1 => 'B'
),
2 => Array
(
0 => 'A',
1 => 'C'
),
3 => Array
(
0 => 'A',
1 => 'C',
2 => 'D'
),
4 => Array
(
0 => 'A',
1 => 'C',
2 => 'E'
),
5 => Array
(
0 => 'X',
1 => 'Y'
),
6 => Array
(
0 => 'X',
1 => 'Y',
2 => 'Z'
),
7 => Array
(
0 => 'X',
1 => 'Y',
2 => 'ZZ'
),
8 => Array
(
0 => 'P',
1 => 'Q'
),
9 => Array
(
0 => 'P',
1 => 'Q',
2 => 'R'
),
10 => Array
(
0 => 'P',
1 => 'Q',
2 => 'R',
3 => 'S'
)
);
I need to generate below array using $testarray (aultidimentional array):
array(A=array(B, C=array(D,E)),
X=array(Y=>array(Z,ZZ)),
P=array(Q=>array(R=>array(S))
At least in the version of PHP I use you can do something like
$testArray = Array(
1 => Array(
'A'=> Array(
//Value of A here
)
'B' => Array(
//Value of B here
)
);
To access them you can write
$testArray[1]['A'];
If you can change the value of $testArray this should help.
This should work. Any refinements (and explanations) would be appreciated.
foreach( $testarray as $values ) {
$depth = count($values);
$ref =& $array;
for( $i=0; $i<$depth; $i++ ) {
if( $i == $depth-1 ) {
$ref[] = $values[$i];
}
else {
if( !is_array( $ref ) || !array_key_exists( $values[$i], $ref ) ) {
$ref[$values[$i]] = array();
}
if( ( $key = array_search( $values[$i], $ref ) ) !== FALSE ) {
unset( $ref[$key] );
}
$ref =& $ref[$values[$i]];
}
}
}
Output:
array
'A' =>
array
0 => string 'B' (length=1)
'C' =>
array
0 => string 'D' (length=1)
1 => string 'E' (length=1)
'X' =>
array
'Y' =>
array
0 => string 'Z' (length=1)
1 => string 'ZZ' (length=2)
'P' =>
array
'Q' =>
array
'R' =>
array
0 => string 'S' (length=1)

Categories