Turn flat array into nested array - php

Just working on something and can't find a simple solution to this problem without just looping through the array with a foreach. Does anyone have a simple solution for this
I want to turn this
&array(4) {
["a"]=>int(0)
["b"]=>int(1)
["c"]=>int(2)
["d"]=>int(3)
}
Into this
array(1) {
["a"]=>
array(1) {
[0]=>
array(1) {
["b"]=>
array(1) {
[0]=>
array(1) {
["c"]=>
array(1) {
[0]=>
array(1) {
["d"]=> int(1) //this value does not matter
}
}
}
}
}
}
}
The values don't matter at all I just need the keys to run against a array_intersect_key_recursive function that I have.
EDIT : The array has changed after testing it needs to be nested as an array of an array

I don't know how this could possibly end up helping you, but it was a fun exercise nonetheless.
$newArray = array();
$last = &$newArray;
$array = array_reverse(array_keys($array));
while ($item = array_pop($array)) {
if (!is_array($last)) {
$last = array();
}
$last[$item] = array(array());
$last = &$last[$item][0];
}
NOTE: I made this answer with the int(1). You said the value is not important so I'm not going to bother changing it for now, but you would have to do a bit more work if the value was important (probably something like get the value from the original array with $item as the key).

Another approach using recursion:
function toNestedArray(array $array, $index = 0) {
$return = array();
if ($index < count($array)) {
$return[$array[$index]] = toNestedArray($array, ++$index);
}
return $return;
}
Usage Example:
$flatArray = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4);
$nestedArray = toNestedArray(array_keys($flatArray));
print_r($nestedArray);
Output:
Array
(
[a] => Array
(
[b] => Array
(
[c] => Array
(
[d] => Array
(
)
)
)
)
)

Related

Generate multidimensional array based on given array

I have an array say,
$arr = ["x", "y", "z"];
What I want to achieve is create another array based on given array such as
$arr1["x" =>["y" => ["z"]]] = "some value";
Any idea to achieve this? Thanks in advance.
Edited:
'some value' is just a dummy data. What I'm trying to achieve is the multidimensional structure.
You can recursively build an array, taking and removing the first element of an array on each call :
function buildArray($arr, $someValue)
{
if (count($arr) == 0)
return $someValue;
// the key is the first element of the array,
// removed and returned at the same time using array_shift()
return [ array_shift($arr) => buildArray($arr, $someValue) ];
}
$arr = ["x", "y", "z"];
$arr1 = buildArray($arr, "some value");
var_dump($arr1);
echo "------------------------" . PHP_EOL;
// note that $arr is preserved
var_dump($arr);
This outputs :
array(1) {
["x"]=>
array(1) {
["y"]=>
array(1) {
["z"]=>
string(10) "some value"
}
}
}
------------------------
array(3) {
[0]=>
string(1) "x"
[1]=>
string(1) "y"
[2]=>
string(1) "z"
}
$keys = array('key1', 'key2', 'key3');
$value = 'some value';
$md = array();
$md[$keys[count($keys)-1]] = $value;
for($i=count($keys)-2; $i>-1; $i--)
{
$md[$keys[$i]] = $md;
unset($md[$keys[$i+1]]);
}
print_r($md);
You need to create recursive function:
function rec_arr($ar, $val){
$res = [];
if(is_array($ar) && count($ar)>0){
$tmp = $ar[0]; // catching the first value
unset($ar[0]); // unset first value from given array
sort($ar); // makes indexes as 0,1,...
$res[$tmp] = rec_arr($ar, $val); // recursion
} else {
return $val; // passing value to the last element
}
return $res;
}
Demo
Outputs:
Array
(
[x] => Array
(
[y] => Array
(
[z] => some value
)
)
)

How to Seperate Array with equals to and create single array

Hi I am working on very complex array operations.
I have $temp variable which stores pipe separated string like Height=10|Width=20
I have used explode function to convert into array and get specific output.
Below code i have try :
$product_attributes = explode("|",$temp)
//below output i get after the explode.
$product_attributes
Array(
[0]=>Height=10
[1]=>width=20
)
But i want to parse this array to separate one.
My expected output :
Array (
[0]=>Array(
[0] => Height
[1] => 10
)
[1]=>Array(
[0]=>Width
[1]=>20
)
)
Which function i need to used to get the desire output ?
Before downvoting let me know if i have made any mistake
You could try the below code. I've tested this and it outputs the result you've shown in your post.
$temp = 'Height=10|Width=20';
$product_attributes = explode('|', $temp);
$product_attributes2 = array();
foreach ($product_attributes as $attribute) {
$product_attributes2[] = explode('=', $attribute);
}
print_r($product_attributes2);
Try Below code
<?php
$temp = "Height=10|Width=20";
$product_attributes = explode("|", $temp);
foreach ($product_attributes as $k => $v) {
$product_attributes[$k] = explode('=', $v);
}
echo '<pre>';
print_r($product_attributes);
?>
check running answer here
Process your result by this:
$f = function($value) { return explode('=', $value); }
$result = array_map($f, $product_attributes);
One more option is to split the values in to one array and then build them from there.
$str = "Height=10|Width=20";
$arr = preg_split("/\||=/", $str);
$arr2= array();
$j=0;
for($i=0;$i<count($arr);$i++){
$arr2[$j][]= $arr[$i];
$arr2[$j][]= $arr[$i+1];
$i++;
$j++;
}
var_dump($arr2);
The output will be:
$arr = array(4){
0 => Height
1 => 10
2 => Width
3 => 20
}
$arr2 = array(2) {
[0]=>
array(2) {
[0]=>
string(6) "Height"
[1]=>
string(2) "10"
}
[1]=>
array(2) {
[0]=>
string(5) "Width"
[1]=>
string(2) "20"
}
}

update a global array within a function

I have a global array in which I am trying to update a value (remain persistent) and then display it.
I get no error but the array never gets updated.
<?php
$anchor = 'bird';
$stuff = array('apple', 'bird', 'frog');
function insert($anchor, $stuff){
foreach($stuff as $part){
$new_array = array($anchor => rand());
if($part == $anchor){
array_push($stuff, $new_array);
}
}
}
for($x = 0; $x < 2; $x++){
insert($anchor, $stuff);
var_dump($stuff);
}
output:
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(4) "bird"
[2]=>
string(4) "frog"
}
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(4) "bird"
[2]=>
string(4) "frog"
}
expected output:
{'bird' => 674568765}
{'bird' => 986266261}
How do I update an array within a function, so that the changes are reflected globally (persistent)?
Pass the variable $stuff by reference. Note the & in the function parameters.
function insert($anchor, &$stuff){ // note the & mark
foreach($stuff as $part){
$new_array = array($anchor => rand());
if($part == $anchor){
array_push($stuff, $new_array);
}
}
}
As others have mentioned: by default, PHP function arguments are passed by value, meaning that a value changed inside a function does not change outside of the function.
I suggest returning the new $stuff value from your function:
<?php
$anchor = 'bird';
$stuff = array('apple', 'bird', 'frog');
function insert($anchor, $stuff){
foreach($stuff as $part){
$new_array = array($anchor => rand());
if($part == $anchor){
array_push($stuff, $new_array);
}
}
return $stuff;
}
for($x = 0; $x < 2; $x++){
$stuff=insert($anchor, $stuff);
}
echo"<pre>".print_r($stuff,true)."</pre>";
?>
Array
(
[0] => apple
[1] => bird
[2] => frog
[3] => Array
(
[bird] => 618490127
)
[4] => Array
(
[bird] => 1869073273
)
)
Other solutions propose passing by reference, to which I'm not opposed. But I have definitely run into buggy code in which it wasn't immediately clear that a function was changing a value, and I've been confused by unexpected loop behavior. As a result, I generally prefer arguably more readable/maintainable code that returns a new value.
See When to pass-by-reference in PHP.
Get technical with Sara Golemon.
If you want changes to a variable that you pass to a function to persist after the function ends, pass the variable by reference:
Change:
function insert($anchor, $stuff)
To
function insert($anchor, &$stuff)

PHP Reconstruct Array

I need to reconstruct an array. Here is the original array:
array(8) {
[0] => array(1)
{
["L_TRANSACTIONID0"] => string(17) "62M97388AY676841D"
}
[1] => array(1)
{
["L_TRANSACTIONID1"] => string(17) "9FF44950UY3240528"
}
[2] => array(1)
{
["L_STATUS0"] => string(9) "Completed"
}
[3] => array(1)
{
["L_STATUS1"] => string(9) "Completed"
}
}
I would like to reconstruct it to be as such:
array(2) {
[0] => array(2)
{
["L_TRANSACTIONID0"] => string(17) "62M97388AY676841D"
["L_STATUS0"] => string(9) "Completed"
}
[1] => array(1)
{
["L_TRANSACTIONID1"] => string(17) "9FF44950UY3240528"
["L_STATUS1"] => string(9) "Completed"
}
}
Notice that the KEYS both match with the numeric representation... Is this at all possible?
edit:
here is my code I am using:
foreach($comparison as $key => $val) {
$findme1 = 'L_TRANSACTID'.$i++;
$findme2 = 'L_STATUS'.$c++;
$arrDisable = array($findme1,$findme2);
if( in_array($key, $arrDisable ) ) {
unset( $comparison[ $key ][$val]);
}
if( in_array($key, $arrDisable) ) {
unset( $comparison[ $key ][$val]);
}
}
Try this
$labels = array('L_TRANSACTIONID', 'L_STATUS');
$res = array();
foreach($arr as $val) {
$key = str_replace($labels, '', key($val));
$res[$key] = isset($res[$key]) ? array_merge($res[$key], $val) : $val;
}
print_r($res);
http://codepad.org/MwqTPqtA
If you are certain the the vector cointains pairs L_TRANSACTIONIDn / L_STATUSn keys,that is to say, for each transactionID, there is a corresponding status, what you can do, is to get the number of id/status records (which should equal the length of the initial array, divided by two), and compose the resultin keys, by increasing the current element count.
Could look something like this:
$numItems = sizeof($myInitialArray) / 2;
$newArray = array();
for($i = 0; $i < $numItems; $i++)
{
$itemID = $i * 2; // since we're getting id/status pairs, we're using a step equal to 2
$newArray[] = array(
("L_TRANSACTIONID" . $i) => $myInitialArray[$itemID], // this is the id value
("L_STATUS" . $i) => $myInitialArray[$itemID + 1] // this is the status for that id
);
}
Hope this helps. Have a great day!

Rebase array keys after unsetting elements [duplicate]

This question already has answers here:
How to re-index the values of an array in PHP? [duplicate]
(3 answers)
Closed 2 years ago.
I have an array:
$array = array(1,2,3,4,5);
If I were to dump the contents of the array they would look like this:
array(5) {
[0] => int(1)
[1] => int(2)
[2] => int(3)
[3] => int(4)
[4] => int(5)
}
When I loop through and unset certain keys, the index gets all jacked up.
foreach($array as $i => $info)
{
if($info == 1 || $info == 2)
{
unset($array[$i]);
}
}
Subsequently, if I did another dump now it would look like:
array(3) {
[2] => int(3)
[3] => int(4)
[4] => int(5)
}
Is there a proper way to reset the array so it's elements are Zero based again ??
array(3) {
[0] => int(3)
[1] => int(4)
[2] => int(5)
}
Try this:
$array = array_values($array);
Using array_values()
Got another interesting method:
$array = array('a', 'b', 'c', 'd');
unset($array[2]);
$array = array_merge($array);
Now the $array keys are reset.
Use array_splice rather than unset:
$array = array(1,2,3,4,5);
foreach($array as $i => $info)
{
if($info == 1 || $info == 2)
{
array_splice($array, $i, 1);
}
}
print_r($array);
Working sample here.
Just an additive.
I know this is old, but I wanted to add a solution I don't see that I came up with myself. Found this question while on hunt of a different solution and just figured, "Well, while I'm here."
First of all, Neal's answer is good and great to use after you run your loop, however, I'd prefer do all work at once. Of course, in my specific case I had to do more work than this simple example here, but the method still applies. I saw where a couple others suggested foreach loops, however, this still leaves you with after work due to the nature of the beast. Normally I suggest simpler things like foreach, however, in this case, it's best to remember good old fashioned for loop logic. Simply use i! To maintain appropriate index, just subtract from i after each removal of an Array item.
Here's my simple, working example:
$array = array(1,2,3,4,5);
for ($i = 0; $i < count($array); $i++) {
if($array[$i] == 1 || $array[$i] == 2) {
array_splice($array, $i, 1);
$i--;
}
}
Will output:
array(3) {
[0]=> int(3)
[1]=> int(4)
[2]=> int(5)
}
This can have many simple implementations. For example, my exact case required holding of latest item in array based on multidimensional values. I'll show you what I mean:
$files = array(
array(
'name' => 'example.zip',
'size' => '100000000',
'type' => 'application/x-zip-compressed',
'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
'deleteUrl' => 'server/php/?file=example.zip',
'deleteType' => 'DELETE'
),
array(
'name' => 'example.zip',
'size' => '10726556',
'type' => 'application/x-zip-compressed',
'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
'deleteUrl' => 'server/php/?file=example.zip',
'deleteType' => 'DELETE'
),
array(
'name' => 'example.zip',
'size' => '110726556',
'type' => 'application/x-zip-compressed',
'deleteUrl' => 'server/php/?file=example.zip',
'deleteType' => 'DELETE'
),
array(
'name' => 'example2.zip',
'size' => '12356556',
'type' => 'application/x-zip-compressed',
'url' => '28188b90db990f5c5f75eb960a643b96/example2.zip',
'deleteUrl' => 'server/php/?file=example2.zip',
'deleteType' => 'DELETE'
)
);
for ($i = 0; $i < count($files); $i++) {
if ($i > 0) {
if (is_array($files[$i-1])) {
if (!key_exists('name', array_diff($files[$i], $files[$i-1]))) {
if (!key_exists('url', $files[$i]) && key_exists('url', $files[$i-1])) $files[$i]['url'] = $files[$i-1]['url'];
$i--;
array_splice($files, $i, 1);
}
}
}
}
Will output:
array(1) {
[0]=> array(6) {
["name"]=> string(11) "example.zip"
["size"]=> string(9) "110726556"
["type"]=> string(28) "application/x-zip-compressed"
["deleteUrl"]=> string(28) "server/php/?file=example.zip"
["deleteType"]=> string(6) "DELETE"
["url"]=> string(44) "28188b90db990f5c5f75eb960a643b96/example.zip"
}
[1]=> array(6) {
["name"]=> string(11) "example2.zip"
["size"]=> string(9) "12356556"
["type"]=> string(28) "application/x-zip-compressed"
["deleteUrl"]=> string(28) "server/php/?file=example2.zip"
["deleteType"]=> string(6) "DELETE"
["url"]=> string(45) "28188b90db990f5c5f75eb960a643b96/example2.zip"
}
}
As you see, I manipulate $i before the splice as I'm seeking to remove the previous, rather than the present item.
I use $arr = array_merge($arr); to rebase an array. Simple and straightforward.
100% working for me ! After unset elements in array you can use this for re-indexing the array
$result=array_combine(range(1, count($your_array)), array_values($your_array));
Late answer but, after PHP 5.3 could be so;
$array = array(1, 2, 3, 4, 5);
$array = array_values(array_filter($array, function($v) {
return !($v == 1 || $v == 2);
}));
print_r($array);
Or you can make your own function that passes the array by reference.
function array_unset($unsets, &$array) {
foreach ($array as $key => $value) {
foreach ($unsets as $unset) {
if ($value == $unset) {
unset($array[$key]);
break;
}
}
}
$array = array_values($array);
}
So then all you have to do is...
$unsets = array(1,2);
array_unset($unsets, $array);
... and now your $array is without the values you placed in $unsets and the keys are reset
In my situation, I needed to retain unique keys with the array values, so I just used a second array:
$arr1 = array("alpha"=>"bravo","charlie"=>"delta","echo"=>"foxtrot");
unset($arr1);
$arr2 = array();
foreach($arr1 as $key=>$value) $arr2[$key] = $value;
$arr1 = $arr2
unset($arr2);

Categories