0

I have a Laravel query returning a list. I need to filter this list and pick a random item after filtering.

$places = getPlaces();
if ( count($places) > 0) {           
    $places = array_filter($places, "filter"); // 2016/08/25: see http://php.net/manual/en/function.array-filter.php

    $randomPlace = $places[rand(0, count($places) - 1)];
}

This give an error:

array_filter() expects parameter 1 to be array, object give

If I cast $places to array the error goes but I get nothing:

$places = getPlaces();
if ( count($places) > 0) {
    $places = (array)$places;      
    $places = array_filter($places, "filter");

    $randomPlace = $places[rand(0, count($places) - 1)];
}

When I check count($places) I see there's only one item. The resultset has several.

To get around the filter issue I use Eloquent's toArray():

if ( count($places) > 0) {

    $places = $places->toArray();

    $places = array_filter($places, "filter");

    if ( count($places) > 0) {
        $randomPlace = $places[rand(0, count($places) - 1)];
    }

}

This works for filter but I land into a couple of challenges:

  1. I can't access $randomPlace as an object e.g. $randomPlace->name. I have to use array access, $randomPlace['name']. Since there are other methods expecting an object this means having to change/convert all these methods.

  2. $places[rand(0, count($places) - 1)] gives an error, e.g.:

    Undefined offset: 4

Other than having to change all methods to use arrays instead of objects (thereby loosing out on functionality), at the moment the only other method off my head is to create a function that iterates over $places and and puts the objects into an array.

Is there a better way of handling this?

Thanks.

1
  • You can either use the collection method $places->filter('filter') or try getting the values only, using array_values($places). My guess is that array_filter preserves the keys and removed the item where key=4. Commented Aug 25, 2016 at 10:08

1 Answer 1

2

It looks like you're working with a collection and are tripping up when converting it to an array in which you can use array_filter on. Instead, use the built-in collection methods for filtering and retrieving a random element:

$randomItem = $places->filter('filter')->random();

In the example above, the argument to the filter() method is the name of your filter function. I'd recommend calling it something other than filter to increase readability. :)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this works perfectly. It was also great learning about collections in PHP. One thing I noticed, though, the collections' filter does not take a string as a parameter but a closure.

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.