Updating any value in multi-dimensional arrays - php

I'm trying to update values in a multi-dimensional array (using a function so it can be done dynamically), but my approach of looping through each values doesn't seem to work. I tried different solutions offered on stackoverflow but I still can't seem to make it work as a function (with dynamic keys). Here is a simple example with a 2 level array, but it should work on any level.
function updateArrayValue($array,$key_to_find,$new_value){
foreach($array as $key => $value){
if($key == $key_to_find){
$value = $new_value;
break; // Stop the loop
}
}
return $array;
}
$array = array("001"=>"red", "002"=>"green", "003"=>array("003-001"=>"blue", "003-002"=>"yellow"));
$array = updateArrayValue($array,"003-001","purple");
var_dump($array);

You need recursion call of function and set new values. Not value only but changed deep array.
function updateArrayValue($array,$key_to_find,$new_value){
foreach($array as $key => $value){
// if value is not an array then try set new value if is search key
if(!is_array($value)){
if($key == $key_to_find) {
$array[$key] = $new_value;
}
}
else {
// otherwise call function again on value array
$array[$key] = updateArrayValue($value, $key_to_find, $new_value);
}
}
return $array;
}
$array = array(
"001"=> "red",
"002"=> "green",
"003"=> array(
"003-001"=> "blue",
"003-002"=> "yellow"
));
$newArray = updateArrayValue($array,"003-001","purple");
var_dump($newArray);

Related

Attempt to retrieve nested key array value given unkown amount of supplied keys into PHP function

I would like to supply a function with an array of keys (unknown quantity) and a value to then set the corresponding nested array value (using those keys and value). I know how to do this for retrieval, just not for assigning. For retrieval, I do:
function test($keys, $value){
$arr = ["key1" => ["key2" => true], "key3" => true];
$nestedArrayValue = $arr;
foreach($keys as $key){
$nestedArrayValue = $arr[$key];
}
return $nestedArrayValue;
}
But when assigning a value, that $nestedArrayValue is a copy, so it won't actually change the $arr. Likewise, if I were to pass by reference where $nestedArrayValue = &$arr, the foreach would override the entire $arr each time. For example:
function test($keys, $value){
$arr = ["key1" => ["key2" => true], "key3" => true];
$nestedArrayValue = &$arr;
foreach($keys as $key){
$nestedArrayValue = $arr[$key];
}
$nestedArrayValue = $value;
var_dump($arr);
}
test(["key1", "key2"], "test value");
//OUTPUT:
string(10) "test value"
The entire $arr gets overridden (which it should). My question is: how do I assign directly to $arr given an unknown amount of keys (as an array)? Is it possible?
UPDATE:
Here's a pseudo code example of what I am trying to do:
// If this is supplied into function:
["key1","key2"]
// Then this is attempted to be returned:
$arr["key1"]["key2"];
I figured out how to do ^ that, but what I can't seem to figure out how to do this:
// If this is supplied for keys:
["key1","key2"]
// And if this is supplied as value:
"test value"
// Then it should attempt to set:
$arr["key1"]["key2"] = "test value"
Is that possible?
You set the $nestedArrayValue reference to the array and in the loop you actually replace the entire array with the value $arr[$key]. It was necessary to change the reference to the next key:
$nestedArrayValue = &$arr;
foreach($keys as $key){
// $nestedArrayValue = $arr[$key];
$nestedArrayValue = &$nestedArrayValue[$key];
}
$nestedArrayValue = $value;
And it would also be good to check the key for existence:
$nestedArrayValue = &$arr;
$found = true;
foreach($keys as $key){
if (array_key_exists($key, $nestedArrayValue)) {
$nestedArrayValue = &$nestedArrayValue[$key];
} else {
$found = false;
break;
}
}
if ($found) {
$nestedArrayValue = $value;
}

remove value from array what the words is not fully match

How i can remove a value from array what is not fully match the letters.
Array code example:
$Array = array(
'Funny',
'funnY',
'Games',
);
How I can unset all values from this array what is 'funny'
I try via unset('funny'); but is not removing the values from array, is removed just if i have 'funny' on array but 'funnY' or 'Funny' not working
Maybe there is some sophisticated solution with array_intersect_key or something which could do this in one line but I assume this approach is more easily read:
function removeCaseInsensitive($array, $toRemove) {
$ret = [];
foreach ($array as $v) {
if (strtolower($v) != strtolower($toRemove))
$ret[] = $v;
}
return $ret;
}
This returns a new array that does not contain any case of $toRemove. If you want to keep the keys than you can do this:
function removeCaseInsensitive($array, $toRemove) {
$keep = [];
foreach ($array as $k => $v) {
if (strtolower($v) != strtolower($toRemove))
$keep[$k] = true;
}
return array_intersect_keys($array, $keep);
}
You can filter out those values with a loose filtering rule:
$array = array_filter($array, function($value) {
return strtolower($value) !== 'funny';
});

PHP - dynamically add dimensions to array

I have a :
$value = "val";
I also have an array :
$keys = ['key1', 'key2', 'key3'...]
The keys in that array are dynamically generated, and can go from 2 to 10 or more entries.
My goal is getting this :
$array['key1']['key2']['key3']... = $value;
How can I do that ?
Thanks
The easiest, and least messy way (ie not using references) would be to use a recursive function:
function addArrayLevels(array $keys, array $target)
{
if ($keys) {
$key = array_shift($keys);
$target[$key] = addArrayLevels($keys, []);
}
return $target;
}
//usage
$keys = range(1, 10);
$subArrays = addARrayLevels($keys, []);
It works as you can see here.
How it works is really quite simple:
if ($keys) {: if there's a key left to be added
$key = array_shift($keys); shift the first element from the array
$target[$key] = addArrayLevels($keys, []);: add the index to $target, and call the same function again with $keys (after having removed the first value). These recursive calls will go on until $keys is empty, and the function simply returns an empty array
The downsides:
Recursion can be tricky to get your head round at first, especially in complex functions, in code you didn't write, but document it well and you should be fine
The pro's:
It's more flexible (you can use $target as a sort of default/final assignment variable, with little effort (will add example below if I find the time)
No reference mess and risks to deal with
Example using adaptation of the function above to assign value at "lowest" level:
function addArrayLevels(array $keys, $value)
{
$return = [];
$key = array_shift($keys);
if ($keys) {
$return[$key] = addArrayLevels($keys, $value);
} else {
$return[$key] = $value;
}
return $return;
}
$keys = range(1, 10);
$subArrays = addARrayLevels($keys, 'innerValue');
var_dump($subArrays);
Demo
I don't think that there is built-in function for that but you can do that with simple foreach and references.
$newArray = [];
$keys = ['key1', 'key2', 'key3'];
$reference =& $newArray;
foreach ($keys as $key) {
$reference[$key] = [];
$reference =& $reference[$key];
}
unset($reference);
var_dump($newArray);

Assigning the same key => value pair to multiple arrays in PHP

I'm trying to write a function that assigns the same key => value pair to multiple arrays. But the assignment doesn't occur.
<?php
// for debugging
error_reporting(E_ALL);
// arrays is an array of reference arrays
function assignKeyValueToArrays($arrays, $key, $value) {
if(!is_scalar($key) || !is_array($arrays)) {
return false;
}
foreach($arrays as $array) {
if(!is_array($array)) return false;
echo "setting $key to $value";
$array[$key] = $value;
}
}
$s = array();
$t = array();
assignKeyValueToArrays(array(&$s, &$t), "a", "blahblah");
// should print array(1) {"a" => "blahblah"} but both print array(0) {}
var_dump($s);
var_dump($t);
?>
The context for this is that I have a script which is doing database queries and assigns keys to both a temporary $queryParams array and also a $jsonResponse array. I could just do two assignments but I wanted a more general solution that could handle more arrays.
You should pass $array to the foreach loop by reference too, like &$array.
Checkout this Demo

php get array element and remove it from array at once

I have array:
$arr = array(
'a' => 1,
'b' => 2,
'c' => 3
);
Is there built-in php function which gets array value by key and then removes element from this array?
I know array_shift and array_pop functions, but I need to get element by custom key, not first/last element. Something like:
$arr; // 'a'=>1, 'b'=>2, 'c'=>3
$elem = array_shift_key($arr, 'b');
echo $elem; // 2
$arr; // 'a'=>1, 'c'=>3
Not sure about native way, but this should work:
function shiftByKey($key, &$array) {
if (!array_key_exists($key, $array)) {
return false;
}
$tmp = $array[$key];
unset($array[$key]);
return $tmp;
}
Edit: Updated it so that array is passed by reference. Else your array stays the same.
As far as I'm aware there's nothing that comes close to that. Can be written easily though:
function array_shift_key(array &$array, $key) {
$value = $array[$key];
unset($array[$key]);
return $value;
}
If you care, validate first whether the key exists in the array and do something according to your error handling philosophy if it doesn't. Otherwise you'll simply get a standard PHP notice for non-existing keys.
function array_shift_key(array &$input, $key) {
$value = null;
// Probably key presents with null value
if (isset($input[$key]) || array_key_exists($key, $input)) {
$value = $input[$key];
unset($input[$key]);
}
return $value;
}

Categories