Установить многомерный массив по ключевому пути из значений массива? - PullRequest
4 голосов
/ 30 июня 2010

Извините за ужасное название, лучшее, что я мог придумать в то время! Скажем, у меня есть массив 'path', например:

array('this', 'is', 'the', 'path')

Каким будет самый эффективный метод для получения массива ниже?

array(
    'this' => array(
        'is' => array(
            'the' => array(
                'path' => array()
            )
        )
    )
)

Ответы [ 5 ]

6 голосов
/ 14 марта 2012

Я использую две аналогичные функции для получения и установки значений по их пути в массиве:

function array_get($arr, $path)
{
    if (!$path)
        return null;

    $segments = is_array($path) ? $path : explode('/', $path);
    $cur =& $arr;
    foreach ($segments as $segment) {
        if (!isset($cur[$segment]))
            return null;

        $cur = $cur[$segment];
    }

    return $cur;
}

function array_set(&$arr, $path, $value)
{
    if (!$path)
        return null;

    $segments = is_array($path) ? $path : explode('/', $path);
    $cur =& $arr;
    foreach ($segments as $segment) {
        if (!isset($cur[$segment]))
            $cur[$segment] = array();
        $cur =& $cur[$segment];
    }
    $cur = $value;
}

Тогда вы используете их так:

$value = array_get($arr, 'this/is/the/path');
$value = array_get($arr, array('this', 'is', 'the', 'path'));
array_set($arr, 'here/is/another/path', 23);
6 голосов
/ 30 июня 2010

Просто переберите его с помощью что-то вроде array_shift или array_pop:

$inarray = array('this', 'is', 'the', 'path',);
$tree = array();
while (count($inarray)) {
    $tree = array(array_pop($inarray) => $tree,);
}

Не тестировано, но это основная структура.Рекурсия также хорошо подходит для этой задачи.В качестве альтернативы, если вы не хотите изменять исходный массив:

$inarray = array('this', 'is', 'the', 'path',);
$result = array();
foreach (array_reverse($inarray) as $key)
    $result = array($key => $result,);
1 голос
/ 30 июня 2010

Одно рекурсивное решение:

function find_in_array(&$array, &$path, $_i=0) {
  // sanity check
  if ( !(is_array($array) && is_array($path)) ) return false;
  $c = count($path); if ($_i >= $c) return false;

  $k = $path[$_i];
  if (array_key_exists($k, $array))
    return ($_i == $c-1) ? $array[$k] : find_in_array($array[$k], $path, $_i+1);
  else
    return false;
}

Параметр $_i предназначен для внутреннего использования и не должен устанавливаться при вызове функции.

1 голос
/ 30 июня 2010
function buildArrayFromPath( $path ) {
  $out = array();
  while( $pop = array_pop($path) ) $out = array($pop => $out);
  return $out;
}
0 голосов
/ 30 июня 2010

не очень элегантно. но это работает

$ start = array ('this', 'is', 'the', 'path')

$ result [$ start [0]] [$ start [1]] [$ start [2]] [$ start [3]] = array ();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...