2

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.

VST
  • 131
  • 1
  • 8
  • Do you need to know where that item is or only if it's there? – Andreas Jul 21 '17 at 18:43
  • Just need to know if every sub-array or sub-sub-array contains the item(in my case `category-id`) or not. If location of item can be found then really great, but "if it's there or not" is also very helpful. – VST Jul 21 '17 at 18:45
  • If it's there can be done by flattening the array and using in_array. That's step one. I guess if true there you need a recursive function to find location. https://stackoverflow.com/questions/4128323/in-array-and-multidimensional-array https://stackoverflow.com/questions/526556/how-to-flatten-a-multi-dimensional-array-to-simple-one-in-php – Andreas Jul 21 '17 at 18:48

3 Answers3

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;
}
Nicholas Summers
  • 3,611
  • 2
  • 16
  • 32
1

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);

Accountant م
  • 4,969
  • 2
  • 30
  • 49
0

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
                )

        )

)
Patrick Simard
  • 1,877
  • 3
  • 18
  • 32