0

I have an array with some elements inside, each one of them has a name and an id. For example:

Array
(
    [0] => stdClass Object
        (
            [id] => 1
            [name] => a
        )

    [1] => stdClass Object
        (
            [id] => 2
            [name] => b
        )

    [2] => stdClass Object
        (
            [id] => 3
            [name] => c
        )

    [3] => stdClass Object
        (
            [id] => 4
            [name] => d
        )

    [4] => stdClass Object
        (
            [id] => 5
            [name] => e
        )

)

And what I want to do with them, is allow some preferred elements to be defined in another array, and then sort this one so that those "preferred" ones will appear first.

For example here, if my user now says that he prefers items with the id's 4, 5, and 6, then the order of these items should result in this:

Array
(
    [0] => stdClass Object
        (
            [id] => 4
            [name] => d
        )

    [1] => stdClass Object
        (
            [id] => 5
            [name] => e
        )

    [2] => stdClass Object
        (
            [id] => 1
            [name] => a
        )

    [3] => stdClass Object
        (
            [id] => 2
            [name] => b
        )

    [4] => stdClass Object
        (
            [id] => 3
            [name] => c
        )

)

The 4 and 5 now appear first, because they were preferred, the fact that 6 doesn't actually exist makes no difference (it was just preferred, not mandatory), and the rest of them are then listed afterwards in an irrelevant order.

Now, statically, I know I can achieve this exact behavior by doing this:

usort($elements, function($a, $b) { return in_array($a->id, [4,5,6]) ? -1 : 1; });

This works, and it will sort the elements with the id's 4 and 5 to the top. But if I want those [4,5,6] to be in a variable, because they come from another source (they aren't static), then I can't make this work... Defining them in an array called $preferred and then using global $preferred inside the function call results in the value of $preferred being NULL.

Which seems weird, because it seems like a sensible thing to be doing.

So what is my alternative then?

Digital Ninja
  • 3,415
  • 5
  • 26
  • 51
  • 1
    don't use global. use `use`. see example #3: http://php.net/manual/en/functions.anonymous.php – Marc B Jun 17 '16 at 14:26

2 Answers2

1

Since you didn't show your code when trying to use global, I can't explain what turned wrong there.

Anyway, as already suggested by @Marc B, the recommended way in your case is to use use rather than global.

So a simple function achieving what you plan looks like:

function move_top($preferred, $elements) {
  usort($elements, function($a, $b) use ($preferred) {
    return in_array($a->id, $preferred) ? -1 : 1;
  });
  print_r($elements);
}
move_top([4,5,6], $elements);
cFreed
  • 4,404
  • 1
  • 23
  • 33
  • $preferred = [4,5,6]; usort($elements, function($a, $b) { global $preferred; return in_array($a->id, $preferred) ? -1 : 1; }); – Digital Ninja Jun 19 '16 at 20:54
  • @ImNotMike Would it be that those 2 statements appear _inside a function body_? In this case, `$preferred = [4,5,6];` is local to the function, while `global $preferred;` is _really_ global. – cFreed Jun 19 '16 at 23:13
  • Correct. Because the framework is such that all my pages' code is defined in methods of the controller class. That settles both cases then, why `global` wouldn't work, and the `use` alternative (which does work inside the method), so I'll accept your answer because everything is here :) (I went with `use` in the end) – Digital Ninja Jun 19 '16 at 23:47
0

Read this.. http://php.net/manual/en/function.usort.php .. hope it helps..

Heres another similar thread Sorting a php array of arrays by custom order

Community
  • 1
  • 1
T.Adak
  • 143
  • 1
  • 11