2

I am working with a Wordpress menu array and I need to loop through it to unset an entry based on a value of a nested object. The way I am currently doing it seems very clunky. I am sure I can somehow loop through the array to accomplish this but it is beyond skills (more of a javascript guy).

While this is in Wordpress I think its more of a general PHP question so I am posting it here.

Here is a breakdown of what I have and what I am trying to do:

Sample of the array

Array
(
    [1] => WP_Post Object
        (
            [ID] => 13378;
            [title] => Courses;
            [current_item_parent] => 1;
        )

    [2] => WP_Post Object
        (
            [ID] => 13375;
            [title] => Images;
            [current_item_parent] => 1;
        )

    [3] => WP_Post Object
        (
            [ID] => 13379;
            [title] => Tests;
            [current_item_parent] => 1;
        )

    [4] => WP_Post Object
        (
            [ID] => 13875;
            [title] => Somethings;
            [current_item_parent] => 1;
        )
)

Basically I want to loop through the array below, if Array->title is equal to "Courses" or "Tests" I want to unset it from the array.

This is what I have so far. The $hide array is not being used but that is what I want to test against. I dont have a foreach loop in there because I cant figure out a way to make it work.

function ad_filter_menu($sorted_menu_objects, $args)
{
  $hide = array('Courses', 'Tests'); //doing nothing right now

  if ($sorted_menu_objects[1]->title == 'Courses') {
    unset($sorted_menu_objects[1]);
  };

  if ($sorted_menu_objects[3]->title == 'Title') {
    unset($sorted_menu_objects[3]);
  };

  return $sorted_menu_objects;
}

The end result should look like this

Array
(
    [2] => WP_Post Object
        (
            [ID] => 13375
            [title] => Images
            [current_item_parent] => 1
        )

    [4] => WP_Post Object
        (
            [ID] => 13875
            [title] => Somethings
            [current_item_parent] => 1
        )
)

2 Answers 2

2

Its always a bit tricky unsetting bits of an array you are actually looping over, so the simple answer is to make a new one as you process the original

function ad_filter_menu($inArr, $args)
{
    $hide = array('Courses', 'Tests'); 

    $newArr = [];   

    foreach ($inArr as $obj) {
        if (! in_array($obj->title, $hide)) {
            $newArr[] = $obj;
        }
    }   
    return $newArr;
}

The function parameter $args does not seem to be used but I left it there in case that was something you were planning to implement later

Of course you can also remove the unwanted items from the original array if you prefer like this

function ad_filter_menu2(&$inArr, $args)
{
    $hide = array('Courses', 'Tests');   

    foreach ($inArr as $idx => &$obj) {
        if (in_array($obj->title, $hide)) {
            unset($inArr[$idx]);
        }
    }   
}

ad_filter_menu2($inArr, 'sssss');
print_r($inArr);
Sign up to request clarification or add additional context in comments.

1 Comment

That works perfectly and it's such a simple approach. Been banging my head against a wall for two hours with this one. Thanks!
1

Just adding some additional ways to solve the problem using built in PHP functions. Note both the below solutions do not mutate the original array but return a new "filtered" array:

function ad_filter_menu($array, $args) {
  $hide = array('Courses', 'Tests');
  $filtered = array_filter($array, function($obj){
    return in_array($obj->title, $hide);
  });

  return $filtered;
}

OR in PHP 7.4

function ad_filter_menu($array, $args) {
  $hide = ['Courses', 'Tests'];
  $filtered = array_filter($array, fn ($obj) => in_array($obj->title, $hide));
  return $filtered;
}

1 Comment

This is a good alternative, but your answer would be improved by adding some explanation about how this will solve the OP's problem - i.e. what using array_filter does to help them and a link to the official PHP documentation for the function would also help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.