用于检查多维数组的递归函数

时间:2015-12-10 14:25:15

标签: php recursion

真的很挣扎。我有一个多维数组n级别。每个阵列级别'我需要检查(类别)的信息,并检查它是否包含任何数组。

我想返回所有具有类别且不包含数组(即叶子)的数组的类别ID。我可以正确地回显输出,但我不知道如何返回数组中的ID(不引用)

我尝试了RecursiveIteratorIterator::LEAVES_ONLYRecursiveArrayIterator,但我认为他们不适合我的情况? (也许我忽视了一些事情)

$array

array(2) {
  ["1"]=>
  string(5) "stuff"
  ["2"]=>
  array(2) {
    ["category"]=>
    string(1) "0"
    ["1"]=>
    array(3) {
      [0]=>
      array(3) {
        ["category"]=>
        string(1) "1"
        ["1"]=>
        string(5) "stuff"
        ["2"]=>
        string(5) "stuff"
      }
      [1]=>
      array(5) {
        ["category"]=>
        string(1) "2"
        ["1"]=>
        string(5) "stuff"
        ["2"]=>
        string(5) "stuff" 
      }
      [1]=>
      array(5) {
        ["1"]=>
        string(5) "stuff"
        ["32"]=>
        string(5) "stuff" 
      }
    }
  }
}

我的功能

public function recurs($array, $cats = [])
{
    $array_cat = '';
    $has_array = false;

    // Check if an id exists in the array
    if (array_key_exists('category', $array)) {
        $array_cat = $array['category'];
    }

    // Check if an array exists within the array
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $has_array = true;
            $this->recurs($value, $cats);
        }
    }

    // If a leaf array
    if (!$has_array && is_numeric($array_cat)) {
        echo "echoing the category here works fine: " . $array_cat . "\n";

        return $array_cat;
    }
}

调用它

$cats_array = $this->recurse($array)

输出回显

echoing the category here works fine: 1
echoing the category here works fine: 2

如何返回数组中的id以在$cats_array变量中使用?

编辑:输出应该匹配echo,所以我应该得到一个包含(1, 2)的数组,因为它们是唯一有类别且没有数组的数组

array(2){
    [0]=>
    int(1) "1"
    [1]=>
    int(1) "2"
}

1 个答案:

答案 0 :(得分:2)

如果我理解正确,这个功能就可以完成这项任务:

function getCategories(array $data)
{
    if ($subArrays = array_filter($data, 'is_array')) {
        return array_reduce(array_map('getCategories', $subArrays), 'array_merge', array());
    };

    return array_key_exists('category', $data) ? array($data['category']) : array();
}

如果数组包含任何子数组,则array_filter将返回它们,您将输入if语句。 array_map将递归地将函数应用于子数组,array_reduce将合并结果。

如果数组不包含任何子数组,则不会输入if语句,并且该函数将返回一个包含该类别的数组(如果存在)。

请注意,您可能需要使用array_unique返回唯一类别。

对于小型性能优化而不是array_key_exists,您可以使用isset($ array [$ key])|| array_key_exists($ key,$ array)。

<强>更新

如果要更新函数以使其工作,则必须递归收集和合并子结果。在下面的例子中,我为此引入了一个新变量:

public function recurs($array, $cats = [])
{
    $result = [];

    $array_cat = '';
    $has_array = false;

    // Check if an id exists in the array
    if (array_key_exists('category', $array)) {
        $array_cat = $array['category'];
    }

    // Check if an array exists within the array
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $has_array = true;
            $result = array_merge($result, $this->recurs($value, $cats));
        }
    }

    // If a leaf array
    if (!$has_array && is_numeric($array_cat)) {
        echo "echoing the category here works fine: " . $array_cat . "\n";

        return [$array_cat];
    }

    return $result;
}