phparray-intersect

Replace algorithm with array_intersect - order of arguments question


I have an algorithm that does some product categories calculations in WordPress... The parts of interest of the algorithm are below:

    foreach ( $product_categories as $product_category ) {
        if ( check_children( $product_category->term_id, $product_ids ) ) {
            // Here we perform some calculations when $product_category->term_id's children categories (their IDs actually) aren't included in the array (of IDs) $product_ids
        }
    }

The check_children function is this:

function check_children( $parent, $term_ids = array() ) {
    $is_latest_child = true;
    $children        = get_term_children( $parent, 'product_cat' ); // For those not familiar with WP, this function returns an array of category IDs that are children of the "$parent" category at question
    if ( count( $children ) > 0 ) { // First of all, this count is obsolete, isn't it? I mean, foreach below already takes care of the case when $children is empty, isn't this so?
        foreach ( $children as $child ) {
            if ( in_array( $child, $term_ids ) ) { // So all that's needed is at least one child category of the $parent at question to be included in the array of "prohibited" categories in $term_ids
                $is_latest_child = false;
                break;
            }
        }
    }
    return $is_latest_child;
}

So what I want is either optimize, or better yet completely wipe the use of check_children with the use of array_intersect... But I'm a little confused about the correct order of arguments. Let me be more specific:

I'm planning to replace this:

if ( check_children( $product_category->term_id, $product_ids ) ) {

with this (I'm leaning towards this more):

if ( count( array_intersect( get_term_children( $product_category->term_id, 'product_cat' ), $product_ids ) ) === 0 ) {

or is it this the correct one:

if ( count( array_intersect( $product_ids, get_term_children( $product_category->term_id, 'product_cat' ) ) ) === 0 ) {

Or doesn't it actually really matter? Remember I want to replace my already existing algorithm with this sorter "workaround".

(I have one or two questions in a comment in the second code block. Could you please answer those too?)

TIA.


Solution

  • I'd say that the check_children() function is pretty well optimized. A conditionally broken loop will have the best chance of outperforming array_intersect() or array_diff() calls because those array functions are not designed to stop iterating until the entire payload is traversed.

    I guess if I had to tweak the function, it would look like this:

    function isLatestChild(int $parent, array $term_ids = []): bool
    {
        if ($term_ids) {  // only bother iterating children if there is a haystack
            foreach (get_term_children($parent, 'product_cat') as $child) {
                if (in_array($child, $term_ids)) {
                    return false;
                }
            }
        }
        return true;
    }