2

I would like to dynamically set/get array's elements with a string as element keys.
So I'm looking for the good way to convert a string into a multiple keys array.
I reach the expected result with that piece of ugly code, which I'm not proud of:

function arrayElementSet($str, $value, array &$array)
{
    $arrayStr = "['".preg_replace('/\./', "']['", $str)."']";
    eval('$array'.$arrayStr.'="'.$value.'";');
}

function arrayElementGet($str, array &$array)
{
    $arrayStr = "['".preg_replace('/\./', "']['", $str)."']";
    eval('$ret=$array'.$arrayStr.';');
    return $ret;
}

$array = array();
arrayElementSet('d0.d1.d2.d4', 'bar', $array);
$wantedElement = arrayElementGet('d0.d1.d2', $array);
print_r($array);
/*
wantedElement looks like:
Array
(
    [d4] => bar
)
$array looks like:
Array
(
    [d0] => Array
        (
            [d1] => Array
                (
                    [d2] => Array
                        (
                            [d4] => bar
                        )
                )
        )
)
*/

But that's pretty ugly, plus I would like to avoid the eval() function.
I'm not particularly attached to an array solution, if there is a nice solution with an object or whatever, I'll take it.


EDIT:

Just to know. Two Helper Functions from Laravel comes out of the box (array_get and array_set):

2 Answers 2

2

Split & traverse:

<?php
function arrayElementSet($str, $value, array &$array, $delimiter = '.') {
  $parent =& $array;
  foreach (explode($delimiter, $str) as $key) {
    if (!array_key_exists($key, $parent)) {
      $parent[$key] = array();
    }  

    $parent =& $parent[$key];
  }

  $parent = $value;
}

function arrayElementGet($str, array &$array, $delimiter = '.') {
  $parent =& $array;
  foreach (explode($delimiter, $str) as $key) {
    if (!array_key_exists($key, $parent)) {
      return null;
    }  

    $parent =& $parent[$key];
  }

  return $parent;
}

$array = array();
arrayElementSet('d0.d1.d2.d4', 'bar', $array);
$wantedElement = arrayElementGet('d0.d1.d2', $array);

print_r($array);
print_r($wantedElement);

http://codepad.viper-7.com/maNmOT

Sign up to request clarification or add additional context in comments.

Comments

0
function insertElementToArray($path, $value, &$array){
    if (!is_array($path)){
        $path = explode('.', $path);
    }
    if (($cnt = count($path)) == 0) return true;

    $defValue = (array_key_exists($key = array_shift($path), $array)) 
        ? $array[$key] 
        : array();
    $array[$key] = ($cnt == 1) ? $value : $defValue;
    insertElementToArray($path, $value, $array[$key]);
}

Using:

insertElementToArray('d0.d1.d2.d4', 'bar', $array);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.