Home > Enterprise >  trying to iterate through array and find the minimum for each group - php
trying to iterate through array and find the minimum for each group - php

Time:10-01

I have a php array and I'm trying to iterate through it and create a new array using the minimum value for distance for each city name. My resulting array only ends up with 1 result instead of what I'm expecting (several).

Here is the input array:

Array
(
    [0] => Array
        (
            [city_name] => Smithtown
            [target_area] => Aiken
            [distance] => 155.65490673533
        )

    [1] => Array
        (
            [city_name] => Smithtown
            [target_area] => Blackville
            [distance] => 74.41221079571
        )

    [2] => Array
        (
            [city_name] => Ridley
            [target_area] => Augusta
            [distance] => 12.48521079571
        )

    [3] => Array
        (
            [city_name] => Ridley
            [target_area] => Dalton
            [distance] => 129.35392949498
        )

)

And here is the desired output array:

Array
(
    [0] => Array
        (
            [city_name] => Smithtown
            [target_area] => Blackville
            [distance] => 74.41221079571
        )

    [1] => Array
        (
            [city_name] => Ridley
            [target_area] => Augusta
            [distance] => 12.48521079571
        )

)

I've tried iterating through it using a foreach loop and running this code against each iteration:

$filteredArray = 
array_filter($employees2, function($element) use($min){
  return isset($element['distance']) && $element['distance'] == $min;
});

CodePudding user response:

One approach is to use array_reduce and an accumulator.

The idea is that the accumulator starts off as an empty array and you look to see if the city has been processed yet. If it hasn't, add it to the accumulator and move on. If it has, then check the distance and replace it if the incoming distance is smaller.

<?php

// https://3v4l.org/gE3kZ

$cities = [
    ['city_name' => 'Smithtown', 'target_area' => 'Aiken', 'distance' => 155.65490673533], 
    ['city_name' => 'Smithtown', 'target_area' => 'Blackville', 'distance' => 74.41221079571], 
    ['city_name' => 'Ridley', 'target_area' => 'Augusta', 'distance' => 12.48521079571], 
    ['city_name' => 'Ridley', 'target_area' => 'Dalton', 'distance' => 129.35392949498], 
];

$groupedByCity = array_reduce($cities, function (array $accumulator, array $city)
{
    $name = $city['city_name'];
    $distance = $city['distance'];

    // This is the key/position which the city is found in the accumulator. 
    // If this is false, then the city has not been processed yet.
    $cityKey = (array_search($name, array_column($accumulator, 'city_name')));

    // City has not been processed yet. Add the whole thing to the accumulator
    if ($cityKey === false) {
        $accumulator[] = $city;
        
    // City is already added, let's check distance and overwrite it if
    // the incoming distance is smaller than the existing one.
    } else {
        $existingDistance = $accumulator[$cityKey]['distance'];

        if ($distance < $existingDistance) {
            $accumulator[$cityKey] = $city;
        }
    }

    return $accumulator;
}, []);

var_dump($groupedByCity);

CodePudding user response:

usort($array, fn($a, $b) => $b['distance'] <=> $a['distance']);

$arr = []; foreach ($array as $v) $arr[$v['city_name']] = $v;

$arr = array_values($arr);

print_r($arr);

Thank you Lawrence Cherone for answering. You are the best!

  • Related