5

The documentation for min() shows the following example:

// Multiple arrays of the same length are compared from left to right
// so in our example: 2 == 2, but 4 < 5
$val = min(array(2, 4, 8), array(2, 5, 1)); // array(2, 4, 8)

Given the following code:

$input = [
    [3, 6],
    [2, 9],
];

var_dump(min(...$input)); // returns [2, 9] as expected

If you make the same array associative, it fails and always seems to just return the first array:

$input = [
    ["three" => 3, "six"  => 6],
    ["two"   => 2, "nine" => 9],
];

var_dump(min(...$input)); // returns ["three" => 3, "six" => 6]

Why?

Here's an example

4
  • For the splat operator, pro tip: associative arrays won't work here. Not sure if this is the issue... Commented Oct 4, 2018 at 15:05
  • The array isn't associative (the child arrays are, but not the array being passed to min()) Commented Oct 4, 2018 at 15:06
  • Ah, right... :) Commented Oct 4, 2018 at 15:06
  • "multiple non-numeric string values will be compared alphanumerically" so maybe it compare "three" and "two" and "three" is before "two". I tried to change your example by keeping the key and changing the 2 and 3 value (2 value for key "three" and 3 value for key "two") -> it still returs the array with key "three" Commented Oct 4, 2018 at 15:10

2 Answers 2

2

According to the documentation values are compared using the standard comparison rules.

In the table of "comparison with various types" there, it states that if both operands are arrays and a key in operand 1 is not present in operand 2, then the arrays are not comparable. This is why min simply returns whatever is the first value in your array.

Specifically, arrays are compared as follows:

  • If one array has fewer values than the other, it is smaller.
  • Otherwise if any key in operand 1 is not in operand 2, the arrays are uncomparable.
  • For each value in operand 1 in turn, compare with the value with the same key in operand 2.
    • If the same, continue comparing values.
    • Otherwise the smaller array is the one with the smaller value.

Because they are not comparable, min is simply returning the first array in the list. If you swap the order, the other array will be returned. You can see this if you sort the array with sort($input). Every time you sort it the array is reversed.

To get the behaviour you desire, sort the arrays based on their values and then fetch the first element. But be aware that this will depend which key you defined first, so ["three" => 3, "six" => 6] is not the same as ["six" => 6, "three" => 3].

usort($input, function($a, $b) { return array_values($a) <=> array_values($b); });
var_dump($input[0]);
Sign up to request clarification or add additional context in comments.

1 Comment

Ahh of course, thanks! I think the confusion came from the wording in the documentation "...compared from left to right", instead of just stating that they're compared using standard array comparison
0

Just convert them to simple arrays and then return the associative array associated to the result of min.

<?php

function array_min_assoc(){
  $args = func_get_args();
  $not_assoc = array_map('array_values',$args);
  $min = min(...$not_assoc);

  $key = array_search($min, $not_assoc);
  if ($key !== false){
    return $args[$key];
  }

}

$input = [
    ["three" => 3, "six"  => 6],
    ["two"   => 2, "nine" => 9],
];

var_dump(array_min_assoc(...$input)); 
/* returns
array(2) {
  ["two"] => int(2)
  ["nine"]=> int(9)
}
*/

Comments

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.