skip to Main Content

I have a multidimensional array whose depth is uncertain or let’s say depends on how many categories & sub-categories(& sub-sub-categories) are there in magento website, as I calling function $product->getCategoryIds().

Now let’s assume I get all product’s(that are added in the cart/checkout) category tree-hierarchy as multidimensional array like below:

Array
(
    [0] => Array
        (
            [0] => 40
        )

    [1] => Array
        (
            [0] => 40
        )

    [2] => Array
        (
        )

    [3] => Array
        (
        )

    [4] => Array
        (
            [0] => 16
        )

    [5] => Array
        (
            [0] => 16
        )

)

But as it is an ecomerce site’s category heirarchy, you can safely imagine, site could have any depth of categories, sub-categories, sub-sub-categories and so on. Unknown hierarchy of product categories so unknown depth of category ids array.

Now comes my confusion and query, how to check if every sub-array and/or sub-sub-array contains a particular category Id(eg. 40 or 16) or not, by using a combination of various php array functions and using as less loops as possible ?

All I can think of is nested for/foreach loops which has performance overheads, so I am looking for better alternatives to that.

3

Answers


  1. It sounds like you are looking for something like this:

    $ids = $product->getCategoryIds();
    $non_empty_ids = array();
    foreach ($ids as $key => $value) {
        if (!count($value)) {
            // The value has no offsets, lets skip this one
            continue;
        }
        $non_empty_ids[] = $value;
    }
    
    Login or Signup to reply.
  2. You can use array_filter() to remove empty categories from the array

    <?php
    
    $myarray =  array('0' => 
                    array('0' => '40'),
                    '1' => array('0' => '40'),
                    '2' => array(),
                    '3' => array(),
                    '4' => array('0' => '16'),
                    '5' => array('0' => '16'),
                    '6' => array('0' => 
                        array('0' => '40'),
                        '1' => array('0' => '40'),
                        '2' => array(),
                        '3' => array(),
                        '4' => array('0' => '16'),
                        '5' => array('0' => '16')
                    )
                );
    
    $b = array_map("array_filter", $myarray);
    echo "<pre>";
    print_r(array_filter($b));
    echo "</pre>";
    ?>
    Result:
    Array
    (
        [0] => Array
            (
                [0] => 40
            )
    
        [1] => Array
            (
                [0] => 40
            )
    
        [4] => Array
            (
                [0] => 16
            )
    
        [5] => Array
            (
                [0] => 16
            )
    
        [6] => Array
            (
                [0] => Array
                    (
                        [0] => 40
                    )
    
                [1] => Array
                    (
                        [0] => 40
                    )
    
                [4] => Array
                    (
                        [0] => 16
                    )
    
                [5] => Array
                    (
                        [0] => 16
                    )
    
            )
    
    )
    
    Login or Signup to reply.
  3. I prefer using recursion when you are not certain about the input(the structure of the array)

    you can use something like this

    function searchCategoriesForValue(array $array, array $needles)
    {
        $matchsCount = 0;
        foreach ($array as $element){
            if(is_array($element)){
                $matchsCount += searchCategoriesForValue($element, $needles);
            }else{
                if(in_array($element, $needles)){
                    $matchsCount ++;
                }
            }
        }
        return $matchsCount;
    }
    

    Example usage

    <?php
    // nested array that has the number 16 six times.
    $array = [  [0,1,2,3,[16,40,[0,1]]],
                [0,1,2,3,[16,40,[0,1]]],
                [0,1,2,3,[16,40,[0,1]]],
                [0,1,2,3,[16,40,[0,1]]],
                [0,1,2,3,[16,40,[0,1]]],
                [],
                [0,1,2,3,[16,40,[0,1]]]];
    $count = searchCategoriesForValue($array,[16]);
    // 16 has been found 6 times
    var_dump($count);
    $count = searchCategoriesForValue($array,[16,40]);
    // 16 and 40 have been found 12 times
    
    exit;
    

    this outputs

    int(6)

    live demo (https://eval.in/835973);

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search