Nick
Nick

Reputation: 1999

Removing array entry based on value of nested object

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

Upvotes: 2

Views: 194

Answers (2)

mikerojas
mikerojas

Reputation: 2338

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

Upvotes: 1

RiggsFolly
RiggsFolly

Reputation: 94672

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

Upvotes: 2

Related Questions