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)
Related
The Array:
$array = [
'A',
'B',
'C'
//and so on
]
Expected result:
$array = [
[
'value' => 'A',
'names' => [
'1' => 'A',
'2' => 'A'
],
'child' => [
'value' => 'B',
'names' => [
'1' => 'B',
'2' => 'B'
],
'child' => [
'value' => 'C',
'names' => [
'1' => 'C',
'2' => 'C'
],
'child' => [
// and so on...
]
]
]
]
];
I've researched a function array_merge_recursive.
But this function doesn't shift array.
Need to achieve: staggered array from simple array.
I've not understood what you want inside names, however this code is generating the array you want:
$array = [
'A',
'B',
'C'
//and so on
];
$result = [];
for($i = count($array) - 1 ; $i >= 0 ; $i--){
$result = [
'value' => $array[$i],
'names' => [
'1' => $array[$i],
'2' => $array[$i],
],
'child' => $result
];
}
Output:
Array
(
[value] => A
[names] => Array
(
[1] => A
[2] => A
)
[child] => Array
(
[value] => B
[names] => Array
(
[1] => B
[2] => B
)
[child] => Array
(
[value] => C
[names] => Array
(
[1] => C
[2] => C
)
[child] => Array
(
)
)
)
)
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);
?>
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', ),
),
)
I have search for a solution for this but couldn't find anything giving me a "straight" multidimensional array back. Flatten is probably not the solution as long as i want to preserve the original sub structure?
In additional i want to summarize qty when the key is repeating.
This is my original array:
Array
(
[60002] => Array
(
[50001] => Array
(
[50002] => Array
(
[10001] => Array
(
[flag] => B
[qty] => 1
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[flag] => M
[qty] => 1
)
[flag] => M
[qty] => 1
)
[flag] => G
[qty] => 1
)
[10001] => Array
(
[flag] => B
[qty] => 1
)
)
What i basically want is to create a new array looking like this:
Array
(
[10001] => Array
(
[flag] => B
[qty] => 2
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[50001] => Array
(
[flag] => M
[qty] => 1
)
[50002] => Array
(
[flag] => M
[qty] => 1
)
[60002] => Array
(
[flag] => G
[qty] => 1
)
)
This is tested.
The key is intval().
$value['qty'] += intval($newArray[$key]['qty']);
If the [$key]['qty'] does not exist the intval() will return a zero. This is much faster than using an if else to check if a [$key]['qty'] already exists.
The only possible problem I could anticipate is if the Flag value is different when the key value is the same:
[10001] => Array(
[flag] => M
[qty] => 1
),
[10001] => Array(
[flag] => B
[qty] => 1
)
When this is an issue I resolve the priority with a logic table in an array.
$priority['M']['B'] = 'M'
$priority['B']['M'] = 'M'
$priority['']['M'] = 'M'
$priority['M'][''] = 'M'
$priority['B'][''] = 'B'
$priority['B'][''] = 'B'
settype($newArray[$key]['flag'],'string');
[$newArray[$key]['flag'] = $priority[$value['flag']][$newArray[$key]['flag']]
Data:
$array = array('60002' => Array('50001' => Array('50002' => Array('10001' => Array('flag' => 'B','qty' => 1),'10002' => Array('flag' => 'B','qty' => 1),'10003' => Array('flag' => 'B','qty' => 2),'flag' => 'M','qty' => 1),'flag' => 'M','qty' => 1),'flag' => 'G','qty' => 1),'10001' => Array('flag' => 'B','qty' => 1));
PHP
$newArray = array();
getValues($data);
function getValues($array){
global $newArray;
foreach ($array as $key => $value){
if(is_numeric($value['qty'])) {
$value['qty'] += intval($newArray[$key]['qty']);
$newArray[$key] = array('flag'=>$value['flag'],'qty'=>$value['qty']);
}
if (gettype($value) != 'array'){return;}
getValues($value);
}
}
ksort($newArray);
var_export($newArray);
Result:
array (
10001 =>
array (
'flag' => 'B',
'qty' => 2,
),
10002 =>
array (
'flag' => 'B',
'qty' => 1,
),
10003 =>
array (
'flag' => 'B',
'qty' => 2,
),
50001 =>
array (
'flag' => 'M',
'qty' => 1,
),
50002 =>
array (
'flag' => 'M',
'qty' => 1,
),
60002 =>
array (
'flag' => 'G',
'qty' => 1,
),
)
This seemed to work:
function extractArray(array $source, array &$destination, $originalIndex)
{
foreach($source as $index => $value)
{
if(is_array($value))
extractArray($value, $destination, $index);
else
$destination[$originalIndex][$index] = $value;
}
}
$test = array(
60002 => array
(
50001 => array
(
50002 => array
(
10001 => array
(
'flag' => 'B',
'qty' => 1
),
10002 => array
(
'flag' => 'B',
'qty' => 1
),
10003 => array
(
'flag' => 'B',
'qty' => 2
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'G',
'qty' => 1
),
10001 => array
(
'flag' => 'B',
'qty' => 1
)
);
$new = array();
foreach($test as $index => $value)
extractArray($value, $new, $index);
var_dump($new);
die();
You can use a recursive approach to iterate over all levels of the array. For each item you check that it is an array and if it has any of the keys you want checked, add the array consisting of the found attributes.
function flattenArray($array, $keysToCheck) {
$result = array();
foreach($array as $item) {
// check if the current array item is a candidate to
// be added to the flattened array
if(is_array($item)) {
$foundAttributes = array();
foreach($item as $key=>$value) {
if(in_array($key, $keysToCheck) {
$foundAttributes[$key] = $value;
}
}
// we found at least one matching attribute
if(count($foundAttributes)) {
array_push($result, $foundAttributes);
}
// recursively go to the next level and merge the results from there
$result = array_merge($result, flattenArray($item, $keysToCheck);
}
}
return $result;
}
// usage example
$flattenedArray = flattenArray($originalArray, array('flag', 'qty'));
The above solution allows you to customise it for other type of objects, by passing different $keysToCheck arguments to the function.
If you also need the flattened array sorted, you can use usort() to achieve this.
Please pardon any syntax errors, I don't have a PHP interpreter at hand.
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));