Skip to content
Advertisement

Filter multidimensional array by lowest price

I’m working with an array that I’d like to filter so it only contains the lowest prices per key. So 50 would only have one unit, same with 100, and that unit would be the lowest price.

Here’s an example of what I’m working with:

$units = [
    50 => [
        41788 => ['StdRate' => 231.0000, 'UnitName' => "NN23"],
        46238 => ['StdRate' => 303.0000, 'UnitName' => "1038"],
        46207 => ['StdRate' => 303.0000, 'UnitName' => "1007"]
    ],
    100 => [
        41570 => ['StdRate' => 299.0000, 'UnitName' => "HH18"],
        46214 => ['StdRate' => 388.0000, 'UnitName' => "1014"]
    ]
];

I wanted to avoid doing this with a complicated foreach loop, so I thought an array_filter would be nice, but having a hard time wrapping my head around it. Or would a foreach be best?

$filtered = array_filter($units, function($a) {

});

Expected Output:

[
    50 => [
        41788 => ['StdRate' => 231.0000, 'UnitName' => "NN23"]
    ],
    100 => [
        41570 => ['StdRate' => 299.0000, 'UnitName' => "HH18"]
    ]
];

Advertisement

Answer

Here is a function that will go through your multi-dimensional array and grab the lowest units. It will retain the key of the big array (50, 100) and the key of the unit it grabbed (41788, 41570). It will not retain multiple values of the same low rate. In those cases it will return the first of the lowest value it found. Might not be exactly what you want, but it should be a good start and you can always modify it later. It uses a nested foreach to get its work done.

Hope this help you out!

function findLows($big) {
    $lowUnits = array();
    foreach($big as $id => $array) {
        $low = false;
        $prev = false;
        foreach($array as $k => $a) {
            if(!$low) {
                $low = $k;
                $prev = $a['StdRate'];
            } else {
                if($a['StdRate'] < $prev) {
                    $prev = $a['StdRate'];
                    $low = $k;
                }
            }
        }
        $lowUnits[$id] = array( $low => $array[$low]);
    }
    return $lowUnits;
}

$bigArray = array();
$bigArray[50][41788] = array('StdRate' => 231.0000, 'UnitName' => "NN23");
$bigArray[50][46238] = array('StdRate' => 303.0000, 'UnitName' => "1038");
$bigArray[50][46207] = array('StdRate' => 303.0000, 'UnitName' => "1007");
$bigArray[100][41570] = array('StdRate' => 299.0000, 'UnitName' => "HH18");
$bigArray[100][46214] = array('StdRate' => 388.0000, 'UnitName' => "1014");

$filtered = findLows($bigArray);

var_dump($filtered);

Will produce:

array(2) {
  [50]=>
  array(1) {
    [41788]=>
    array(2) {
      ["StdRate"]=>
      float(231)
      ["UnitName"]=>
      string(4) "NN23"
    }
  }
  [100]=>
  array(1) {
    [41570]=>
    array(2) {
      ["StdRate"]=>
      float(299)
      ["UnitName"]=>
      string(4) "HH18"
    }
  }
}
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement