Joseph
Joseph

Reputation: 2726

PHP: Minimum value in 2D array

I have a 2D array in the format:

[
[1, 23, 20],
[2, 45, 30],
[4, 63, 40],
...
]

I am trying to search the array and return elements [0] and [1] from the row where element [1] is lowest. I have the following code to return the lowest value in [1] but I'm not sure how to get element [0] as well.

$min = PHP_INT_MAX;
foreach ($test as $i) {
    $min = min($min, $i[1]);
}

In the above example I would return [1, 23]

Thanks,

Upvotes: 0

Views: 1038

Answers (6)

ircmaxell
ircmaxell

Reputation: 165191

You could use array_reduce:

$array = array(
    array(1, 23, 20),
    array(2, 45, 63),
    array(4, 63, 40),
);
$callback = function ($a1, $a2) {
    if ($a1[1] >= $a2[1]) {
        return $a2;
    } else {
        return $a1;
    }
}
$min = array_reduce($array, $callback, array(0, PHP_INT_MAX, 0));
var_dump($min); // array(1, 23, 20);

Now, this will likely have issues if you have multiple elements with identical [1] elements... But it transparently handles the case where the array is empty. And in general, all you need to do is do your comparison in the callback function for all "filtering" type problems where you can abstract the filtering to a comparison of 2 elements. So you do string comparison, etc to determine which of the 2 is better...

And it should be more efficient than a sort, since it only requires a single pass over the array (It's O(n) whereas sorting is O(n log n) and at worst O(n^2))...

Upvotes: 1

MrGlass
MrGlass

Reputation: 9252

you should just grab the array key of the smallest number:

$min = PHP_INT_MAX;
$minkey = 0;
foreach ($test as $key => $i) {
    if($min > $i[1]) {
        $min = $i[1];
        $minkey = $key;
    }
}

then, you can just access the whole thing with $test[$minkey]

Upvotes: 0

Yanick Rochon
Yanick Rochon

Reputation: 53516

You can use a simple min (O(n)) loop like you did, and array_slice to assign the first two indexes when a lowest is found :

$min = PHP_INT_MAX;
$arrMin = array();
foreach ($test as $i) {
    if ($i[1] < $min) {
       $min = $i[1];
       $arrMin = array_slice($i, 0, 2);
    }
}

Upvotes: 0

Hamish
Hamish

Reputation: 23316

You'll need to introduce some basic logic:

$result = array(0, PHP_INT_MAX);
foreach($test as $i)
   if($i < $result[1])
      $result = array($i[0], $i[1]);

Upvotes: 0

xzyfer
xzyfer

Reputation: 14125

This will do the job.

$min0 = PHP_INT_MAX;
$min1 = PHP_INT_MAX;
foreach ($test as $i) {
    if($i[1] < $min1)
    {
        $min0 = $i[0];
        $min1 = $i[1];
    }
}

This will result in $min0 == 1 and $min1 == 23

Upvotes: 0

lonesomeday
lonesomeday

Reputation: 237847

You should use usort for this:

usort($test, function($a, $b) {
    return $a[1] - $b[1];
});

$min = $test[0];

Note that this uses anonymous functions, which were introduced in PHP 5.3. In previous versions, you need to use named functions and pass the name as a string to usort.

Upvotes: 1

Related Questions