Editing associative array while retaining reference for preparation to JSON encode - php

Is there any common way to edit associative array while retaining reference to original array and making the array be prepared for JSON encode?
An easy way is to rearrange array to new one, but I am thinking that better practice is to go recursively and edit it live.

Here is my function for live editing JSON array with PHP:
function editJSON(&$target, &$aimer){
$found = false;
$result = 0;
foreach($aimer as $ak => $av){
foreach($target as $tk => $tv){
if ($tk == $ak){
$found = true;
$result = 1;
if (is_array($tv) && is_array($av)) editJSON($target[$tk], $aimer[$ak]);
}
if (!$found && is_array($tv)) $result += editJSON($target[$tk], $aimer);
}
if ($found && !is_array($av)) $target[$ak] = $av;
}
return $result;
}
Its fast and tested:
$target = array( 'z'=>array('v'=>1, 'c'=>2, 'g'=>3),
'b'=>array(
'a'=>array(
'b'=>array('g'=>array('c'=>11, 'd'=>13), 'b'=>array('x'=>91, 'y'=>92)),
'e'=>array('m'=>2)
)
),
'd'=>array(
'a'=>array(
'b'=>array('g'=>array('c'=>11, 'd'=>13))
)
)
);
$aimer = array(
'a'=>array(
'b'=>array('g'=>array('c'=>998, 'hh'=>999))
)
);
echo 'Target array:';
echo '<br />';
print_r($target);
echo '<br />';
echo 'Aiming array:';
echo '<br />';
print_r($aimer);
echo '<br />';
$result = editJSON($target, $aimer);
echo 'Resulting array:';
echo '<br />';
print_r($target);
echo '<br />';
echo 'JSON has been modified ' . $result . ' times.';
Will output:
Target array:
Array ( [z] => Array ( [v] => 1 [c] => 2 [g] => 3 ) [b] => Array ( [a] => Array ( [b] => Array ( [g] => Array ( [c] => 11 [d] => 13 ) [b] => Array ( [x] => 91 [y] => 92 ) ) [e] => Array ( [m] => 2 ) ) ) [d] => Array ( [a] => Array ( [b] => Array ( [g] => Array ( [c] => 11 [d] => 13 ) ) ) ) )
Aiming array:
Array ( [a] => Array ( [b] => Array ( [g] => Array ( [c] => 998 [hh] => 999 ) ) ) )
Resulting array:
Array ( [z] => Array ( [v] => 1 [c] => 2 [g] => 3 ) [b] => Array ( [a] => Array ( [b] => Array ( [g] => Array ( [c] => 998 [d] => 13 [hh] => 999 ) [b] => Array ( [x] => 91 [y] => 92 ) ) [e] => Array ( [m] => 2 ) ) ) [d] => Array ( [a] => Array ( [b] => Array ( [g] => Array ( [c] => 998 [d] => 13 [hh] => 999 ) ) ) ) )
JSON has been modified 2 times.
EDIT: Added functionality for adding values to array and counting edits.

Related

PHP Return by reference

<?php
Class A {
public static array $data = ["a" => [0, 1], "c" => [10, 1]];
public static function getData($a): array {
return self::$data[$a];
}
}
// FIRST
print_r(A::$data);
print("<BR>");
// SECOND
$c = A::getData("c");
$c[0] = [20];
print_r(A::$data);
print("<BR>");
// THIRD
A::$data["c"] = [20];
print_r(A::$data);
print("<BR>");
RESULT
Array ( [a] => Array ( [0] => 0 [1] => 1 ) [c] => Array ( [0] => 10 [1] => 1 ) )
Array ( [a] => Array ( [0] => 0 [1] => 1 ) [c] => Array ( [0] => 10 [1] => 1 ) )
Array ( [a] => Array ( [0] => 0 [1] => 1 ) [c] => Array ( [0] => 20 [1] => 1 ) )
SECOND didn't work.
So I changed getData($a) with &getData($a)
But still not solved.
WHY?
Wasn't it "return by reference" error?
How can I fix it?

how can I find value in sub multidimensional array?

I have this array:
Array ( [0] => Array ( [asset] => track [path] => media/promenade_web/AUDIO/promenade-arkadiev.mp3 [file_name] => promenade-arkadiev [permission_audio_play_synchronization] => Array ( [synchronization] => Array ( [constraint] => Array ( [numberOfMeasures] => Array ( [startMeasure] => 1 [number] => 10 ) [qualityOfResource] => medium ) [requirement] => Array ( ) [condition] => Array ( ) ) [play] => Array ( [constraint] => Array ( [numberOfMeasures] => Array ( [startMeasure] => 1 [number] => 10 ) [qualityOfResource] => medium [spatial] => iso3166:CH,IT [count] => 10 [datetime] => Array ( [start] => 2017-08-16 [end] => 2017-10-20 ) [accumulated] => P30D [format] => mp3,wav ) [requirement] => Array ( ) [condition] => Array ( ) ) ) ) [1] => Array ( [asset] => track [path] => media/promenade_web/AUDIO/promenade-arkadiev_lo.mp3 [file_name] => promenade-arkadiev_lo [permission_audio_play_synchronization2] => Array ( [play] => Array ( [constraint] => Array ( [numberOfMeasures] => Array ( [startMeasure] => 1 [number] => 10 ) [qualityOfResource] => medium [spatial] => iso3166:CH,IT [count] => 10 [datetime] => Array ( [start] => 2017-08-16 [end] => 2017-10-20 ) [accumulated] => P30D [format] => mp3,wav ) [requirement] => Array ( [prepay] => Array ( [amount] => 0.99 [currency] => EUR ) ) [condition] => Array ( ) ) ) ) )
How can I find a value with foreach, regardless of the number of subarrays?
I've tried with this code, but it doesn't work:
function recursive_array_search($needle, $haystack, $currentKey = '') {
foreach($haystack as $key=>$value) {
if (is_array($value)) {
$nextKey = recursive_array_search($needle,$value, $currentKey . '[' . $key . ']');
if ($nextKey) {
return $nextKey;
}
}
else if($value==$needle) {
return is_numeric($key) ? $currentKey . '[' .$key . ']' : $currentKey;
}
}
return false;
}
I always use following on multi dimensional array
$arr = array(array('id'=>1,'name'=>'nilesh'),array('id'=>2,'name'=>'ajay'));
echo "<pre>";
print_r($arr[array_search('nilesh', array_column($arr,'name'))]);
echo "</pre>";

Prepare Tree in php

I'm having following array.
Array
(
[a] => Array
(
[d] => Array
(
[f] => Array
(
)
[g] => Array
(
[h] => Array
(
)
[i] => Array
(
)
)
[j] => Array
(
)
)
[e] => Array
(
)
)
[b] => Array
(
)
[c] => Array
(
)
)
I have tried with below code but not getting required output.
str($treeArr);
function str($arr){
foreach($arr as $key=>$value){
if(!empty($value)){
echo $key.">";
str($value);
}
else{
echo $key."<br>";
}
}
}
I need following output.
a>d>f
a>d>g>h
a>d>g>i
a>d>j
a>e
b
c
Hi guys,is this what you want?
$a=array('a'=>array('d'=>array('f'=>array(),
'g'=>array('h'=>array(),
'i'=>array()),
'j'=>array()),
'e'=>array()),
'b'=>array(),
'c'=>array()
);
str($a);
function str($arr){
static $temp=array();
foreach($arr as $k=>$v){
$temp[]=$k;
if(!empty($v)){
str($v);
}else{
$str=implode(">",$temp);
echo $str."\n";
}
array_pop($temp);
}
}
output:
a>d>f
a>d>g>h
a>d>g>i
a>d>j
a>e
b
c

Creating nested parent child array from multi dimensional array in php

I have this array
$array = Array
(
[a] => Array
(
[0] => b
[1] => h
)
[b] => c
[c] => d
[h] => m
)
And I need to convert the array to like below
Array
(
[a] => Array
(
[b] => Array
(
[c] => Array
(
[d] => Array
(
)
)
)
[h] => Array
(
[m] => Array
(
)
)
)
)
I already asked this question for One Dimensional array.
I tried with [Creating nested parent child array from one dimensional array in php and I got the below array
Array
(
[a] => Array
(
[b] => Array
(
[a] => Array
(
[h] => Array
(
[b] => Array
(
[c] => Array
(
[d] => Array
(
)
[h] => Array
(
[m] => Array
(
)
)
)
)
)
)
)
)
)
How to Check wheather the key is present in multi dimensional array and if present add the child to the existing key. Help to resolve the Problem. Thanks in Advance
<?php
$array = array(
'a' => array(0=>'b',1=>'h'),
'b' => 'c',
'c' => 'd',
'h' => 'm',
);
$newArray = array();
$secondarray = array();
$part = &$newArray;
$i=1;
foreach($array as $first => $second)
{
if($i==1)
{
$firstone=$first;
}
else
{
if($i==count($array))
{
$newArray[$first] = array($second => array());
$secondarray[$firstone]=$newArray;
}
else
{
$part = &$part[$first];
$part[$second] = array();
}
}
$i++;
}
echo '<pre>';print_r($secondarray);
output
Array
(
[a] => Array
(
[b] => Array
(
[c] => Array
(
[d] => Array
(
)
)
)
[h] => Array
(
[m] => Array
(
)
)
)
)

PHP recursive function return (true) not working [duplicate]

This question already has answers here:
How to use return inside a recursive function in PHP
(4 answers)
Closed 9 months ago.
Given groups of pairs in each level of the structure below, I want to find if there's a "loop" of connecting points. (if "b" on level 0 has a match on "a" on the next level).
I'm using a recursive function to test it and it's working fine. But when I test the return value it fails:
The code:
$tracker=array();
array_push($tracker, 0);
if (findloop(1, $candidates[0]['pairs'][0]['b'])){
echo "<h1>a path has been found</h1><pre>";
print_r($tracker);
echo "</pre>";
}else{
echo "<h3>no loop found</h3><pre>";
print_r($tracker);
echo "</pre>";
}
The function:
function findloop($level, $value){ // so far.. only progression...
echo "<p>level $level, $value</p>";
global $candidates;
global $tracker;
foreach($candidates[$level]['pairs'] as $key=>$pair){
if($pair['a']==$value){
array_push($tracker, $key);
if($level==sizeof($candidates)-1){
echo "omgggggg";
return true;
}else{
findloop($level+1, $pair['b']);
}
}
}
}
The result:
level 1, 19
level 2, 15
level 3, 18
omgggggg
no loop found < - - - - - - - function does (?) return true but it fails
Array
(
[0] => 0
[1] => 1
[2] => 0
[3] => 1
)
The structure:
Array
(
[0] => Array
(
[angle] => 41.7
[pairs] => Array
(
[0] => Array
(
[a] => 6
[b] => 19
)
[1] => Array
(
[a] => 19
[b] => 6
)
)
)
[1] => Array
(
[angle] => 11.8
[pairs] => Array
(
[0] => Array
(
[a] => 15
[b] => 19
)
[1] => Array
(
[a] => 19
[b] => 15
)
)
)
[2] => Array
(
[angle] => 14.3
[pairs] => Array
(
[0] => Array
(
[a] => 15
[b] => 18
)
[1] => Array
(
[a] => 16
[b] => 17
)
[2] => Array
(
[a] => 17
[b] => 16
)
[3] => Array
(
[a] => 18
[b] => 15
)
)
)
[3] => Array
(
[angle] => 29.5
[pairs] => Array
(
[0] => Array
(
[a] => 6
[b] => 18
)
[1] => Array
(
[a] => 18
[b] => 6
)
)
)
)
The initial return is fine but the calls further up the chain aren't getting this result. In your else you need to return the result:
if($level==sizeof($candidates)-1){
echo "omgggggg";
return true;
}else{
return findloop($level+1, $pair['b']);
}

Categories