Set multidimensional array in PHP - php

I have string
$s = 'controller/front/home';
value
$v = "some value";
and array
$a = [];
What is the best way to make multidimensional array like that?
$a['controller']['front']['home'] = $v;
[edit]
I don't know how many parts (separated by /) string $s can have, so manual array building by exploded parts is the last option I would consider.

I've found this after a small research:
PHP dynamic array path access
By this article, I've adapted it to following
$path = 'controller/front/home';
$value = 'some value';
$parts = explode('/', $path);
$arrayPath = [];
$temp = &$arrayPath;
foreach($parts as $part) {
if(!isset($temp[$part])) {
$temp[$part] = [];
}
$temp = &$temp[$part];
}
$temp = $value;
var_dump($arrayPath);
Prints:
array (size=1)
'controller' =>
array (size=1)
'front' =>
array (size=1)
'home' => string 'some value' (length=10)

$a = $v; foreach (array_reverse(explode('/', $s)) as $i) $a = array($i => $a);

You can do it like this
$array = explode('/', $s);
and then :
$a[$array[0]][$array[1]][$array[2]] = $v;

Related

Extract numbers separated by special char from string

If I have a string like:
123*23*6594*2*-10*12
How can I extract the single numbers, in the string separated by *? That is, I want this output:
a=123, b=23, c=6594, d=2, e=-10, f=12.
Flexible:
$vars = range('a', 'z');
$vals = explode('*', $string);
$result = array_combine(array_slice($vars, 0, count($vals)), $vals);
Result:
Array
(
[a] => 123
[b] => 23
[c] => 6594
[d] => 2
[e] => -10
[f] => 12
)
Just for the sheer fun of setting the result as an iterable (rather than an actual array) with the alpha keys in a slightly different manner:
$data = '123*23*6594*2*-10*12';
function dataseries($data) {
$key = 'a';
while (($x = strpos($data, '*')) !== false) {
yield $key++ => substr($data, 0, $x);
$data = substr($data, ++$x);
}
yield $key++ => $data;
}
foreach(dataseries($data) as $key => $value) {
echo $key, ' = ', $value, PHP_EOL;
}
Requires PHP >= 5.5.0
You can use simple as this :
$str = "123*23*6594*2*-10*12";
$arr = explode("*",$str);
$arr['a']=$arr[0];
$arr['b']=$arr[1];
$arr['c']=$arr[2];
$arr['d']=$arr[3];
$arr['e']=$arr[4];
$arr['f']=$arr[5];
echo "a=" .$arr['a'] ." b=". $arr['b']." c=". $arr['c']." d=". $arr['d']." e=". $arr['e']." f=". $arr['f'];
EDIT:
To accomplish Rizier123 wish :
$str = "123*23*6594*2*-10*12";
$arr = explode("*",$str);
$vars = range('a', 'z');
foreach ($arr as $val => $key){
echo $vars[$val]."=".$key."<br>";
}
something like:
list($a,$b,$c,$d,$e,$f) = explode("*", $str);
Just a guess ;)

Split a string into keys of associative arrays (PHP)

Do you have an idea, how can a string be converted to a variable, e.g.
there is a string -> $string = 'one|two|three';
there is an array -> $arr = array('one' => array('two' => array('three' => 'WELCOME')));
I want to use all with explode(); exploded values to access the array $arr. I tried this code:
$c = explode('|', $string);
$str = 'arr[' . implode('][', $c) . ']';
echo $$str;
It doesnt work, sadly :( Any ideas?
You're doing it wrong.
You can do what you want with a loop to go through the array level by level
$string = 'one|two|three';
$arr = array('one' => array('two' => array('three' => 'WELCOME')));
$c = explode('|', $string);
$result = $arr;
foreach($c as $key)
$result = $result[$key];
echo $result; // WELCOME
Here's a sort of recursive function:
$ex_keys = array('one', 'two', 'three');
$ex_arr = array('one' => array('two' => array('three' => 'WELCOME')));
function get_recursive_var($keys, $arr) {
if (sizeof($keys) == 1)
return $arr[$keys[0]];
else {
$key = array_shift($keys);
return get_recursive_var($keys, $arr[$key]);
}
}
var_dump(get_recursive_var($ex_keys, $ex_arr));

'cascading' explode string in php

How to explode this string :
00004.00001.00003.00001.00003
in an array like this :
array (size=3)
0 => string '00004' (length=5)
1 => string '00004.00001' (length=10)
2 => string '00004.00001.00003' (length=15)
3 => string '00004.00001.00003.00001.00003' (length=20)
Thx
$array = explode('.', '00004.00001.00003.00001.00003');
foreach($array as $key => $value) {
if($array[$key - 1]) {
$array[$key] = $array[$key - 1] . '.' . $value;
}
}
Explode it first as you would normally do $arr = explode('.', $str); and then build desired array with two loops.
Another version using array_map() :
$arr = explode('.', '00004.00001.00003.00001.00003');
$arr[] = 'blank';
$array = array_map(function(){
global $arr;
array_pop($arr);
return implode($arr);
}, $arr);

How to set a deep array in PHP

Assume I have the following function
function setArray(&$array, $key, $value)
{
$array[$key] = $value;
}
In the above function, key is only at the first level, what if I want to set the key at the 2nd or 3rd levels, how to rewrite the function?
e.g.
$array['foo']['bar'] = 'test';
I want to use the same function to set the array value
This one should work. Using this function you can set any array element in any depth by passing a single string containing the keys separated by .
function setArray(&$array, $keys, $value) {
$keys = explode(".", $keys);
$current = &$array;
foreach($keys as $key) {
$current = &$current[$key];
}
$current = $value;
}
You can use this as follows:
$array = Array();
setArray($array, "key", Array('value' => 2));
setArray($array, "key.test.value", 3);
print_r($array);
output:
Array (
[key] => Array
(
[value] => 2
[test] => Array
(
[value] => 3
)
)
)
You can use array_merge_recursive
$array = array("A" => "B");
$new['foo']['bar'] = 'test';
setArray($array, $new);
var_dump($array);
Output
array (size=2)
'A' => string 'B' (length=1)
'foo' =>
array (size=1)
'bar' => string 'test' (length=4)
Function Used
function setArray(&$array, $value) {
$array = array_merge_recursive($array, $value);
}
this function should do it, the key should be an array, for example array('foo', 'bar')
function setArray(&$array, array $keys, $value) {
foreach($keys as $key) {
if(!isset($array[$key])) {
$array[$key] = array();
}
$array = &$array[$key];
}
$array = $value;
}
$arr = array();
setArray($arr, array('first', 'second'), 1);
var_dump($arr);
// dumps array(1) { ["first"]=> array(1) { ["second"]=> int(1) } }
Tested and works.
Use array_replace_recursive instead of array_merge_recursive as it handles same-key scenario correctly. See this https://3v4l.org/2ICmo
Just like this:
function setArray(&$array, $key1, $key2, $value)
{
$array[$key1][$key2] = $value;
}
But why you want to use function? Using it like this:
setArray($array, 'foo', 'bar', 'test');
takes more time to write something like this:
$array[1][2] = 'test';

Swap two key/value pairs in an array

I have an array:
$array = array('a' => 'val1', 'b' => 'val2', 'c' => 'val3', 'd' => 'val4');
How do I swap any two keys round so the array is in a different order? E.g. to produce this array:
$array = array('d' => 'val4', 'b' => 'val2', 'c' => 'val3', 'a' => 'val1');
Thanks :).
I thought there would be really simple answer by now, so I'll throw mine in the pile:
// Make sure the array pointer is at the beginning (just in case)
reset($array);
// Move the first element to the end, preserving the key
$array[key($array)] = array_shift($array);
// Go to the end
end($array);
// Go back one and get the key/value
$v = prev($array);
$k = key($array);
// Move the key/value to the first position (overwrites the existing index)
$array = array($k => $v) + $array;
This is swapping the first and last elements of the array, preserving keys. I thought you wanted array_flip() originally, so hopefully I've understood correctly.
Demo: http://codepad.org/eTok9WA6
Best A way is to make arrays of the keys and the values. Swap the positions in both arrays, and then put 'em back together.
function swapPos(&$arr, $pos1, $pos2){
$keys = array_keys($arr);
$vals = array_values($arr);
$key1 = array_search($pos1, $keys);
$key2 = array_search($pos2, $keys);
$tmp = $keys[$key1];
$keys[$key1] = $keys[$key2];
$keys[$key2] = $tmp;
$tmp = $vals[$key1];
$vals[$key1] = $vals[$key2];
$vals[$key2] = $tmp;
$arr = array_combine($keys, $vals);
}
Demo: http://ideone.com/7gWKO
Not ideal but does what you want to do:
$array = array('a' => 'val1', 'b' => 'val2', 'c' => 'val3', 'd' => 'val4');
$keys = array_keys($array);
swap($keys, 0, 3);
$values = array_values($array);
swap($values, 0, 3);
print_r(array_combine($keys, $values)); // Array ( [d] => val4 [b] => val2 [c] => val3 [a] => val1 )
function swap (&$arr, $e1, $e2)
{
$temp = $arr[$e1];
$arr[$e1] = $arr[$e2];
$arr[$e2] = $temp;
}
Of course you should also check if both indexes are set in swap function (using isset)
Can't you just store the value to a variable for each?
$val1 = $array[0];
$val2 = $array[3];
$array[0] = $val2;
$array[3] = $val1;
You can use this function to swap any value in array to any key .
/**
* switch value with value on key in given array
* array_switch( array( a, b ,c), c,0 );
* will return array(c, b, a);
*
*
* #param array $array
* #param mixed $value
* #param mixed $key
* #return array
*/
public static function array_switch(&$array, $value, $key)
{
// find the key of current value
$old_key = array_search($value, $array);
// store value on current key in tmep
$tmp = $array[$key];
// set values
$array[$key] = $value;
$array[$old_key] = $tmp;
return $array;
}
I know this is quite old, but I needed this, and couldn't find anything satisfactory. So I rolled my own, and decided to share.
Using just one simple loop, this code is super readable to anyone.
I didn't benchmark, but I have a feeling it's not even that bad compared to the other array_keys, array_values, array_combine versions, even when going through a long array.
Should work for both numerical and string keys alike (only tested with string keys)
It's also easy to implement a check, if one or both keys not found and then throw error or return original array, or whatever you need
function arraySwap(array $array, $key1, $key2) {
$value1 = $array[$key1];
$value2 = $array[$key2];
$newArray = [];
foreach( $array as $key => $value ) {
if ($key === $key1) {
$newArray[$key2] = $value2;
} else if ($key === $key2) {
$newArray[$key1] = $value1;
} else {
$newArray[$key] = $value;
}
}
return $newArray;
}

Categories