This question already has an answer here:
PHP Get value from config array
(1 answer)
Closed 7 years ago.
I have this key "this.key.exists". Key can be: a.b.c.d.e.f etc. this is only example.
And i want to check if exists in array:
$array = [ // depth of array and number of values are variable
'this' => [
'key' => [
'exists' => 'some value' // this is what am i looking for
],
'key2' => [
'exists' => 'some value' // this is not what am i looking for
],
],
'that' => [
'this' => [
'key' => [
'exists' => 'some value' // this is not what am i looking for
],
]
]
];
I need to find this key for update his value.
$array['this']['key']['exists'] = 'need to set new value';
Thanks for help
$str = "this.key.exists";
$p = &$array; // point to array root
$exists = true;
foreach(explode('.', $str) as $step) {
if (isset($p[$step])) $p = &$p[$step]; // if exists go to next level
else { $exists = false; break; } // no such key
}
if($exists) $p = "new value";
Related
An array with the following structure
[
'name' => :string
'size' => :string|int
]
must be recursively converted into an object anytime it encounters this structure in iteration.
So, I wrote these functions
// Converts an array into the instance of stdclass
function to_entity(array $file){
$object = new stdclass;
$object->name = $file['name'];
$object->size = $file['size'];
return $object;
}
// Converts required arrays into objects
function recursive_convert_to_object(array $files){
foreach ($files as $name => $file) {
// Recursive protection
if (!is_array($file)) {
continue;
}
foreach ($file as $key => $value) {
if (is_array($value)) {
// Recursive call
$files[$name] = recursive_convert_to_object($files[$name]);
} else {
$files[$name] = to_entity($file);
}
}
}
return $files;
}
Now, when providing an input like this:
$input = [
'translation' => [
1 => [
'user' => [
'name' => 'Tom',
'size' => 2
]
]
]
];
And calling it like this, it works as expected (i.e an ecountered item user is being converted to stdclass via to_entity() function:
print_r( recursive_convert_to_object($input) );
Now here's the problem:
if an input like this gets provded (i.e one item with the key 4 => [...] is added) it no longer works throwing E_NOTICE about undefined indexes both name and size.
$input = [
'translation' => [
1 => [
'user' => [
'name' => 'Tom',
'size' => 2
]
],
4 => [
'user' => [
'name' => 'Tom',
'size' => 5
]
],
]
];
Let me repeat, that the depth of the target array is unknown. So no matter what depth is, it must find and convert an array into the object.
So where's the logical issue inside that recursive function?
Not sure if this is the best method to solve the problem, but as you already have invested some time in it.
The issue is that once you have replaced some of the content in the array, you put an object back in the array. Then when you test if it's an array in
if (is_array($value)) {
which it isn't so you convert it into an entity, it's trying to convert the object again.
To stop this happening...
if ( !is_object($value)) {
$files[$name] = to_entity($file);
}
Suppose I have an array like this:
$myArray = [
[ 'id' => 1, 'name' => 'Some Name' ],
[ 'id' => 2, 'name' => 'Some Other Name ]
]
Now if want to get the second item without using the index ($myArray[1]), but instead by using the value of name which is Some Other Name, how do I do that?
I don't want to loop through the entire array just for one value, so how can I write this in a way that I don't explicitly loop through the array myself? I looked into array_search(), but couldn't find examples where $myArray contains additional arrays as items.
you can use array_filter() function:
<?php
$myArray = [
['id' => 1, 'name' => 'Some Name'],
[
'id' => 2, 'name' => 'Some Other Name'
]
];
$filterData = array_filter($myArray, function ($data) {
return $data['name'] == "Some Other Name";
});
var_dump($filterData);
die;
?>
Not entirely sure what you're trying to do, but you can index the array on name:
echo array_column($myArray, null, 'name')['Some Other Name']['id']; //echos 2
To do it once and have access to all name:
$result = array_column($myArray, null, 'name');
echo $result['Some Other Name']['id']; // echos 2
echo $result['Some Name']['id']; // echos 1
This is the simpliest solution:
$requiredItem = null;
foreach ($myArray as $item) {
if ($item['name'] === 'Some Other Name') {
$requiredItem = $item;
// `break` allows you to STOP iterating over array
break;
}
}
print_r($requiredItem);
All other solutions will include full loop over your array at least once.
This question already has answers here:
How to access and manipulate multi-dimensional array by key names / path?
(10 answers)
Closed 5 years ago.
I'm trying to remove an element in a multidimensional array.
The element which is needs to be removed is given by a string like globals.connects.setting1. This means I'm intend to modify an array like this:
// Old Array
$old = array(
"globals" => array(
"connects" => array(
"setting1" => "some value",
"setting2" => "some other value",
"logging" => array()),
"someOtherKey" => 1
));
// After modification
$new = array(
"globals" => array(
"connects" => array(
"setting2" => "some other value",
"logging" => array()),
"someOtherKey" => 1
));
Unfortunately I do not know either the "depth" of the given string nor the exact structure of the array. I'm looking for a function like unsetElement($path, $array) which returns the array $new, if the array $old and globals.connects.setting1 is given as argument.
I'd like to avoid the use of the eval() function due to security reasons.
$testArr = [
"globals" => [
"connects" => [
'setting1' => [
'test' => 'testCon1',
],
'setting2' => [
'abc' => 'testCon2',
],
],
],
'someOtherKey' => [],
];
$pathToUnset = "globals.connects.setting2";
function unsetByPath(&$array, $path) {
$path = explode('.', $path);
$temp = & $array;
foreach($path as $key) {
if(isset($temp[$key])){
if(!($key == end($path))) $temp = &$temp[$key];
} else {
return false; //invalid path
}
}
unset($temp[end($path)]);
}
unsetByPath($testArr, $pathToUnset);
I have an array:
<?php
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
];
I also have a string:
$string = 'fruits[orange]';
Is there any way to check if the - array key specified in the string - exists in the array?
For example:
<?php
if(array_key_exists($string, $array))
{
echo 'Orange exists';
}
Try this one. Here we are using foreach and isset function.
Note: This solution will also work for more deeper levels Ex: fruits[orange][x][y]
Try this code snippet here
<?php
ini_set('display_errors', 1);
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]
];
$string = 'fruits[orange]';
$keys=preg_split("/\[|\]/", $string, -1, PREG_SPLIT_NO_EMPTY);
echo nestedIsset($array,$keys);
function nestedIsset($array,$keys)
{
foreach($keys as $key)
{
if(array_key_exists($key,$array))://checking for a key
$array=$array[$key];
else:
return false;//returning false if any of the key is not set
endif;
}
return true;//returning true as all are set.
}
It would be a lot easier to check the other way around. As in check if the key is in the string. Since keys are unique, there's no way you have duplicates.
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]
];
$string = 'fruits[orange]';
$keys = array_keys($array['fruits']);
foreach($keys as $fruit) {
if(false !== stripos($string, $fruit)) {
return true;
}
}
While this solution is not necessarily ideal, the problem to begin with isn't exactly common.
You can walk recursively:
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]
];
$exists = false;
$search = "orange";
array_walk_recursive($array, function ($val, $key) use (&$exists,$search) {
if ($search === $key) { $exists = true; }
});
echo ($exists?"Exists":"Doesn't exist");
Prints:
Exists
Example: http://sandbox.onlinephpfunctions.com/code/a3ffe7df25037476979f4b988c2f36f35742c217
Instead of using regex or strpos like the other answers, you could also simply split your $string on [ and resolve the keys one by one until there's only one key left. Then use that last key in combination with array_key_exists() to check for your item.
This should work for any amount of dimensions (eg fruit[apple][value][1]).
Example:
<?php
$arr = [
'fruits' => [
'orange' => 'value'
]
];
// Resolve keys by splitting on '[' and removing ']' from the results
$keys = 'fruits[orange]';
$keys = explode("[", $keys);
$keys = array_map(function($s) {
return str_replace("]", "", $s);
}, $keys);
// Resolve item.
// Stop before the last key.
$item = $arr;
for($i = 0; $i < count($keys) - 1; $i++) {
$item = $item[$keys[$i]];
}
// Check if the last remaining key exists.
if(array_key_exists($keys[count($keys)-1], $item)) {
// do things
}
You can explode and check the indices of the array.
$array = array(
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]);
$string = 'fruits[orange]';
$indexes = (preg_split( "/(\[|\])/", $string));
$first_index= $indexes[0];
$seconnd_index= $indexes[1];
if(isset($array[$first_index][$seconnd_index]))
{
echo "exist";
}
else
{
echo "not exist";
}
DEMO
I need to delete a key in an array from a string.
String is translations.fr
Array is
[
...,
translations => [
fr => [
...
],
es => [
...
]
],
...,
]
Result must be :
[
...,
translations => [
es => [
...
]
],
...,
]
I think, using exlpode and unset is the good way.
Can you help me ? Thank's
Try this
unset(ArrayName[key][key].....)
Try this :
If you want to replace the same array and delete the "fr" completely
$translationArray = unset($translationArray['fr']);
If you want to retain the previous array and save the changes in a new one
$translationArrayNew = unset($translationArray['fr']);
I think this is what you're looking for:
$str = 'translations.fr';
$exploded = explode('.', $str);
$array = [
'translations' => [
'fr' => 'fr value',
'es' => 'es value',
]
];
unset($array[$exploded[0]][$exploded[1]]);
With explode you put your string into an array containing 2 keys:
0 => translations
1 => fr
This accesses the 'translations' key within your array
$array[$exploded[0]]
and this accesses the 'fr' key within 'translations'
$array[$exploded[0]][$exploded[1]]
it's like writing: $array['translations]['fr']
Solution :
public function deleteKeyV3($keyToDelete) {
$keys = explode('.', $keyToDelete);
$result = &$array;
foreach ($keys as $key) {
if (isset($result[$key])) {
if ($key == end($keys)) {
unset($result[$key]);
} else {
$result = &$result[$key];
}
}
}
}