Q:

Comparing n values in a single array

So I have a associative array that looks like the following:
   #items: array:84 [
0 => {#513
  +"name": "Spencer, Heaney and Von"
  +"id": 49
  +"lon": 40.68
  +"lat": 90.25
  +"catId": 2
  +"locId": 49
  +"distance": 48.796277782319
}
1 => {#514
  +"name": "Yost-Terry"
  +"id": 16
  +"lon": 40.07
  +"lat": 90.99
  +"catId": 2
  +"locId": 16
  +"distance": 52.598218030179
}
2 => {#515
  +"name": "Mills-Okuneva"
  +"id": 98
  +"lon": 40.84
  +"lat": 89.79
  +"catId": 1
  +"locId": 98
  +"distance": 59.083838249165
}
3 => {#516
  +"name": "D'Amore Ltd"
  +"id": 67
  +"lon": 40.88
  +"lat": 89.82
  +"catId": 1
  +"locId": 67
  +"distance": 61.538239638491
}
4 => {#517
  +"name": "D'Amore Ltd"
  +"id": 67
  +"lon": 40.88
  +"lat": 89.82
  +"catId": 2
  +"locId": 67
  +"distance": 61.538239638491
}
5 => {#518
  +"name": "Kuvalis, Denesik and Terry"
  +"id": 14
  +"lon": 41.03
  +"lat": 90.05
  +"catId": 1
  +"locId": 14
  +"distance": 71.218957454573
}

Now what I am trying to do is iterate through each location and check if the value after it is the same, or the next two values are the same, all the way to the next n values being the same. 
So basically if a user passes 4 categories in then it will take the first locations name then check the next 3 locations names and see if they are the same, if so it adds all instances of a location with that name to a collection.
(Note this is faker generated data so the location "Labadie-Bauch" wont have the same catId in all 4 entries the live data)
The following code is my attempt at solving this, which isn't working. I believe this will work for if a user only passes 2 categories but not if they pass n categories.
$final = collect();

dd($locations);
for($i = 0; $i < count($locations);$i++){
    for($j = 1; $j < count($request->categories);$j++){
        if($locations[$i]->name == $locations[$i+$j]->name){
            //add to final collection
        }
    }
}
dd($final);

A:

This isn't an especially pretty solution, as it involves looping over the data three times.
$locations = [/* ... */];
$categories = [1, 2];
$collection = [];

// Reduce locations to an array categories, grouped by location name
$grouped = array_reduce($locations, function ($grouped, $location) {
    $grouped[$location->name][] = $location->catId;
    return $grouped;
}, []);

// Filter the location groups to remove any locations that do not match all categories
$grouped = array_filter($grouped, function ($_categories) use ($categories) {
    return ! array_diff($categories, $_categories);
});

// Append locations with matching name and category to collection
foreach ($locations as $location) {
    if (isset($grouped[$location->name]) && in_array($location->catId, $categories)) {
        $collection[] = $location;
    }
}

var_dump($collection);

Here's a working example: https://3v4l.org/mBZZn
I notice that you're using Laravel, so if the $locations are in a Collection, you may be able to chain some of this logic using the available Collection methods.

