Получение всех детей для глубокого многомерного массива - PullRequest
5 голосов
/ 28 декабря 2011

У меня есть такой массив:

array(
    array(
        'id' => 1,
        'children' => array(
            array(
                'id' => 2,
                'parent_id' => 1
            ),
            array(
                'id' => 3,
                'parent_id' => 1,
                'children' => array(
                    array(
                        'id' => 4,
                        'parent_id' => 3
                    )
                )
            )
        )
    )
);

Массив идет глубже, если это необходимо. Мне нужно получить детей для любого заданного идентификатора.

Спасибо.

Ответы [ 4 ]

7 голосов
/ 28 декабря 2011
function getChildrenOf($ary, $id)
{
  foreach ($ary as $el)
  {
    if ($el['id'] == $id)
      return $el;
  }
  return FALSE; // use false to flag no result.
}

$children = getChildrenOf($myArray, 1); // $myArray is the array you provided.

Если я что-то не упустил, итерируйте по массиву, ища что-то, что соответствует ключу id и идентификатору, который вы ищете (затем верните его в результате).Вы также можете выполнять итеративный поиск (и дать мне секунду, чтобы опубликовать код, который вместо этого будет проверять клавишу parentId) ...

-

Рекурсивная версия,Включает дочерние элементы:

function getChildrenFor($ary, $id)
{
  $results = array();

  foreach ($ary as $el)
  {
    if ($el['parent_id'] == $id)
    {
      $results[] = $el;
    }
    if (count($el['children']) > 0 && ($children = getChildrenFor($el['children'], $id)) !== FALSE)
    {
      $results = array_merge($results, $children);
    }
  }

  return count($results) > 0 ? $results : FALSE;
}

Рекурсивная версия, исключая дочерние элементы

function getChildrenFor($ary, $id)
{
  $results = array();

  foreach ($ary as $el)
  {
    if ($el['parent_id'] == $id)
    {
      $copy = $el;
      unset($copy['children']); // remove child elements
      $results[] = $copy;
    }
    if (count($el['children']) > 0 && ($children = getChildrenFor($el['children'], $id)) !== FALSE)
    {
      $results = array_merge($results, $children);
    }
  }

  return count($results) > 0 ? $results : FALSE;
}
1 голос
/ 28 декабря 2011

Вы можете использовать встроенный код для этого

$iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iter as  $val) {
    if (isset($val['id']) && $val['id'] === 3) {
        print_r($val['children']);
        break;
    }
}
1 голос
/ 28 декабря 2011

Наивным подходом было бы выполнить исчерпывающий поиск по дереву путем обхода дерева, начиная с корня, пока не будет найден узел. В худшем случае вы должны выполнить итерацию всего дерева, только чтобы заметить, что искомый узел является последним или вообще не существует.

Лучшим подходом было бы изначально создать индекс, который отображает идентификаторы на узлы внутри дерева. При этом вам нужно будет только пройти по всему дереву один раз, а затем получить прямой доступ к узлу через индекс. В идеале индексация должна выполняться во время построения древовидной структуры из плоских данных.

Так что, если у вас есть плоский массив, как в ваш другой вопрос , вы можете построить дерево и индекс из него всего за одну итерацию плоского массива:

* * 1010

Этот код взят из моего ответа на аналогичный вопрос . Последний размещенный вами массив находится в $tree['children']. Каждый узел в нем может быть доступен с помощью $index[12345].

0 голосов
/ 28 декабря 2011
function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
{
    if( !is_array($haystack) ) {
        return false;
    }

    foreach( $haystack as $key => $val ) {
        if( is_array($val) && $subPath = array_searchRecursive($needle, $val,     $strict, $path) ) {
            $path = array_merge($path, array($key), $subPath);
            return $path;
        } elseif( (!$strict && $val == $needle) || ($strict && $val['id'] === $needle) ) {
            $path[] = $key;
            return $path;
        }
    }
    return false;
}

array_searchRecursive( 5, $arr );

- ссылка: http://greengaloshes.cc/2007/04/recursive-multidimensional-array-search-in-php/

...