使用php计算关联数组中元素的深度

时间:2011-10-10 20:40:58

标签: php recursion associative-array

我一直在努力编写一个递归函数来给我一个给定元素的深度。我似乎无法理解递归。这就是我所拥有的,但它无法正常工作:

function getDepth($a, $e, $depth = 0) {
  foreach ($a as $key => $val) {
    if (is_array($val)) {
      if ($key == $e) {
        return $depth;
      }
      return getDepth($val, $e, $depth + 1);
    }
    else {
      if ($val == $e) {
        return $depth;
      }
      else {
        return 1;
      }
    }
  }
}

任何人都可以帮助指出我在这里做错了什么吗?在此先感谢您的帮助。

编辑:

@Brad @Amber @Viktor谢谢,但这似乎也不起作用。这就是我所追求的......我有一个看起来像这样的数组:

[antonio] => Array
(
    [ian] => Array
        (
            [molly] => Array
                (
                    [blake] => blake
                )

        )

    [shonda] => Array
        (
            [dana] => dana
            [james] => james
        )

    [nels] => Array
        (
            [jason] => jason
            [danny] => danny
        )

    [molly] => Array
        (
            [blake] => blake
        )

    [blake] => blake
    [travis] => travis
)

这是一棵树,我希望找到给定名字的深度级别。所以,我需要传递一个名字,比如blake。然后我会想要遍历整个树,每当我发现它在不同层次的树中时(并且实际上是在这个例子中)时,跟踪blake的深度。假设最高深度级别为0,则antonio下的blake级别=> ian =>莫莉=> blake是3,但他在antonio下的等级=> blake是1,所以我想返回1.我将不得不遍历整个树(幸运的是这个函数不会经常被调用)以确保我在给定用户的树中找到了最浅的深度。再次感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

基本上,为了使递归正确,如果您知道函数中有数组,则在其上运行相同的函数。我们添加最深的路径到目前为止+1。最后,你得到了你想要的东西。

function getDepth($a) {
    $max=0;
    foreach ($a as $val) {
        if (is_array($val)) {
            $tmp_depth=getDepth($val);
            if ($max<($tmp_depth)) {
                $max=$tmp_depth;
            }
        }
    }
    return $max+1;
}

我没有对此进行基准测试。毫无疑问,如果重要的话,可以提高速度。

答案 1 :(得分:0)

function getDepth($a, $e, $depth = 0) {
  $lower  = false;   //  meaning 'not found'
  // as you are looking for the less deep value, first check for values and then for arrays
  // so there are chances when you do not traverse all the tree for a match
  foreach ($a as $key => $val) if ($val == $e) return $depth;
  foreach ($a as $key => $val) {
    if (is_array($val)) {
      $tmp = getDepth($val, $e, $depth + 1);
      if($tmp) if ($lower === false || $tmp < $lower) $lower = $tmp;
    }
  }
  return $lower;
}

$x=array( 
  antonio => Array(
    ian => Array(
       molly => Array(
          blake => blake,
          jhonyDeep => jhonyDeep
       )
    ),
    shonda => Array(
       dana => dana,
       james => james
    ),
    nels => Array (
       jason => jason,
       danny => danny
    ),
    molly => Array(
       blake => blake
    ),
    blake => blake,
    travis => travis
  )
);


echo getDepth($x, blake);      // gives 1
echo getDepth($x, danny);      // gives 2
echo getDepth($x, jhonyDeep);  // gives 3

答案 2 :(得分:0)

类似于我以前的版本,但针对性能进行了优化(并且要小心,未经测试)

function getDepth($a, $e, $depth = 0, $lower = false) {
  // $lower = false means 'not found'
  // as you are looking for the less deep value, first check for values and then for arrays
  // so there are chances when you do not traverse all the tree for a match
  foreach ($a as $key => $val) if ($val == $e) return $depth;
  foreach ($a as $key => $val) {
    if (is_array($val)) {
      $tmp = false;
      if($lower===false || $lower > $depth) $tmp = getDepth($val, $e, $depth + 1, $lower);  // to do not recurse innecesary
      if($tmp) {
        if($tmp==$depth+1) return $tmp;  //optimization: $depth+1 can't be beat by other values
        if ($lower === false || $tmp < $lower) $lower = $tmp;
      }
    }
  }
  return $lower;
}

$x=array( 
  antonio => Array(
    ian => Array(
       molly => Array(
          blake => blake,
          jhonyDeep => jhonyDeep
       )
    ),
    shonda => Array(
       dana => dana,
       james => james
    ),
    nels => Array (
       jason => jason,
       danny => danny
    ),
    molly => Array(
       blake => blake
    ),
    blake => blake,
    travis => travis
  )
);


echo getDepth($x, blake);      // gives 1
echo getDepth($x, danny);      // gives 2
echo getDepth($x, jhonyDeep);  // gives 3