Dynamic multidimensional array keys for class property - php

Is it possible to create multidimensional array with its keys defined in array? Yes, it is, according to bunch of Stack Overflow answers. Here is one: Dynamic array keys
function insert_using_keys($arr, array $path, $value) { // See linked answer }
$arr = create_multi_array($arr, array('a', 'b', 'c'), 'yay'));
print_r($arr);
Prints
Array ( [a] => Array ( [b] => Array ( [c] => yay ) ) )
Would the same be possible for class properties?
This is a barebone version of my Collection class. Method set_at should add a multidimensional array to $data property the same way insert_using_keys function does.
class A {
protected $data = array();
public function set($key, $value) {
$this->data[$key] = $value;
}
public function set_at(array $keys, $value) {
}
}
I've tried a several modifications of the insert_using_keys to no avail. I was able to set the keys to the property, but not assign value "to the last one".
Would someone point me in the right direction please? Thanks in advance!

In the midst of recreating the "key-setter" function, I was able to answer my own question (was it your intention all along, Stefan?).
Here is the code:
public function set_at(array $keys, $value) {
$first_key = array_shift($keys);
foreach (array_reverse($keys) as $key) {
$value = array($key => $value);
}
$this->data[$first_key] = $value;
}

Related

PHP: array search when array doesn't start on zero

I'm trying to find a key in an array that doesn't start with zero.
This is my not so elegant solution:
private $imagetypes = [
1 => [
'name' => 'banner_big',
'path' => 'campaigns/big/'
],
2 => [
'name' => 'banner_small',
'path' => 'campaigns/small/'
],
// ...
If i use $key = array_search('banner_big', array_column($this->imagetypes, 'name')); the result is 0
I came up with this solution but I feel like I needlessly complicated the code:
/**
* #param string $name
* #return int
*/
public function getImagetypeFromName($name)
{
$keys = array_keys($this->imagetypes);
$key = array_search($name, array_column($this->imagetypes, 'name'));
if ($key !== false && array_key_exists($key, $keys)) {
return $keys[$key];
}
return -1;
}
Is there a better solution then this.
I can't change the keys in.
Just save indexes
$key = array_search('banner_big',
array_combine(array_keys($imagetypes),
array_column($imagetypes, 'name')));
demo on eval.in
The problem is array_column will return a new array (without the existing indexes)
So in your example.
$key = array_search('banner_big', array_column($this->imagetypes, 'name'));
var_dump($key);
//$key is 0 as 0 is the key for the first element in the array returned by array_column.
You can mitigate against this by creating a new array with the existing keys.
That's because array_column() generates another array (starting at
index zero), as you may have imagined. An idea to solve this would be to
transform the array with array_map(), reducing it to key and image
name (which is what you're searching for). The keys will be the same,
and this can be achieved with a simple callback:
function($e) {
return $e['name'];
}
So, a full implementation for your case:
public function
getImagetypeFromName($name)
{
$key = array_search($name, array_map(function($e) {
return $e['name'];
}, $this->imagetypes));
return $key ?: -1;
}

Adding items to an array using a function in php does not work

I have created an associative array
$prijs = array (
"Black & Decker Accuboormachine" => 148.85,
"Bosch Boorhamer" => 103.97,
"Makita Accuschroefmachine" => 199.20,
"Makita Klopboormachine" => 76.00,
"Metabo Klopboor" => 119.00
);
Now I have to add a value to the array and I would like to use a function for this.
function itemToevoegen($array, $key, $value){
$array[$key] = $value;
}
Then I call the function:
itemToevoegen($prijs, "Bosch GBH 18 V-LI", 412.37);
I have tried this without putting the array name in the input parameters but that does not work either.
=================== EDIT =====================
While typing this I thought I had to return the value, but that does not give me the desired result either.
function itemToevoegen($array, $key, $value){
return $array[$key] = $value;
}
Could someone help me with this and tell me what I am missing here?
Thanks in advance.
Two options:
Passing by reference
You can pass a variable by reference to a function so the function can modify the variable.
function itemToevoegen(&$array, $key, $value){
$array[$key] = $value;
}
or return array back and set new value
function itemToevoegen($array, $key, $value){
$array[$key] = $value;
return $array;
}
$prijs = itemToevoegen($prijs, "Bosch GBH 18 V-LI", 412.37);
Passing by Reference:
function itemToevoegen(&$array, $key, $value){
$array[$key] = $value;
}
Pass by reference means that you can modify the variables that are seen by the caller. To do it, prepend an ampersand to the argument name in the function definition.
By default the function arguments are passed by value, so that if the value of the argument within the function is changed, it does not get changed outside of the function.

foreach loop using $this as key and value

I want to make a foreach loop like this one
foreach ($this->data['array'] as $this->data['key'] => $this->data['value'])
{
echo $this->data['value'];
}
Yet the $this->data['value'] is never created. Why is this and what am I doing wrong?
In my understanding, you have a class in which there is a variable or array name $data.
Now, you added an array in $data with an index named 'array', right?
If so, this code will work properly -
class myClass{
public $data = array(); //$data is an array
function print_array(){
foreach ($this->data['array'] as $this->data['key'] => $this->data['value'])
{
echo $this->data['value'];
}
}
}
$ob = new myClass(); // object declaration for your class
array_push($ob->data,'array'); // added a value to the $data array.
$ob->data['array'] = array(); // the newly added value is declared as an index of an array
// Now simply push values to the array named $data['array']
array_push($ob->data['array'],1);
array_push($ob->data['array'],2);
array_push($ob->data['array'],3);
$ob->print_array(); // call the print_array() function. $this will be passed to that function
Hope this will help to understand.
If you still have problem, please comment.
To have a clear understanding, you can visit this link. There are lots of simple and interesting examples explained!
Happy Coding!
I think $this is for current class object reference not for an array
foreach ($this->data['array'] as $k => $v)
{
echo $v;
$this->data['key'][] = $k;
$this->data['value'][] = $v;
}
print_r($this->data['key']);
print_r($this->data['value']);
If:
class YourClass {
private data = array(
'array' => array(
'key1' => 'val1',
'key2' => 'val2', etc.
)
);
then it should be:
foreach ($this->data['array'] as $key => $val)
{
echo $val;
// if you want to add keys and vals to data array:
$this->data[$key] = $val;
}

Find key in nested associative array

The other day I asked a question related to this, and I got an answer, but it did not do what I wanted. Here is the method I have for traversing a multidimensional associative array, checking whether a key is in the array (from the answer to my previous question):
private function checkKeyIsInArray($dataItemName, $array)
{
foreach ($array as $key => $value)
{
// convert $key to string to prevent key type convertion
echo '<pre>The key: '.(string) $key.'</pre>';
if ((string)$key == $dataItemName)
return true;
if (is_array($value))
return $this->checkKeyIsInArray($dataItemName, $value);
}
return false;
}
Here is my array stucture:
Array (
[0] => Array ( [reset_time] => 2013-12-11 22:24:25 )
[1] => Array ( [email] => someone#example.com )
)
The method traverses the first array branch, but not the second. Could someone explain why this might be the case please? It seems I am missing something.
The problem is that you return whatever the recursive call returns, regardless of whether it succeeded or failed. You should only return if the key was found during the recursion, otherwise you should keep looping.
private function checkKeyIsInArray($dataItemName, $array)
{
foreach ($array as $key => $value)
{
// convert $key to string to prevent key type convertion
echo '<pre>The key: '.(string) $key.'</pre>';
if ((string)$key == $dataItemName)
return true;
if (is_array($value) && $this->checkKeyIsInArray($dataItemName, $value))
return true;
}
return false;
}
BTW, why is this a non-static function? It doesn't seem to need any instance properties.

Find array key in php and change its value or contents?

Given a multi-dimensional array that you don't necessarily know the structure of; how would one search for a key by name and change or add to it's contents? The value of the key could be either a string or an array and the effects should be applied either way--I had looked at array_walk_recursive, but it ignores anything that contains another array...
Does this work?
function arrayWalkFullRecursive(&$array, $callback, $userdata = NULL) {
call_user_func($callback, $value, $key, $userdata);
if(!is_array($array)) {
return false;
}
foreach($array as $key => &$value) {
arrayWalkFullRecursive($value);
}
return true;
}
arrayWalkFullRecursive($array,
create_function( // wtb PHP 5.3
'&$value, $key, $data',
'if($key == $data['key']) {
$value = $data['value'];
}'
),
array('key' => 'foo', 'value' => 'bar')
);
Array keys in PHP are ints and strings. You can't have an array array key. So yeah, array_walk_recursive() is what you want.

Categories