5
\$\begingroup\$

My user defined comparison compare function is defined with an array:

$boardkey_to_values=Array(19=>2601248,23=>2601248,39=>2603445,
    43=>2256319,47=>2632006,59=>2603445,63=>2232152,67=>2260713,71=>2632006,...)

so 23>19 EDIT:23=19, 39>19, 39<23,...

I have an array of values $board_id, and I want to get the array of all the keys for the minimum values.

Here's my solution, but I don't think it is really intuitive.

$min_key=Array(0);
foreach ($board_id as $key => $value) {
if ($boardkey_to_values[$board_id[$min_key[0]]]>$boardkey_to_values[$value])
    $min_key=Array($key);
if ($boardkey_to_values[$board_id[$min_key[0]]]==$boardkey_to_values[$value] && $min_key[0]!=$key)
    $min_key[]=$key;
}

Here is an example to show how this should behave:

say $board_id = [19,23,39,47,71]

it will look at the values corresponding to this numbers [2601248,2601248,2603445,2632006,2632006]

it looks for the smallest value: 2601248

so the result ($min_key should be [19,23])

\$\endgroup\$
  • \$\begingroup\$ Why is 23 > 19 when they both map to the same value? Shouldn't they be equal? \$\endgroup\$ – David Harkness Mar 26 '13 at 22:00
  • \$\begingroup\$ Yes you're right 23=19, I have edited my question \$\endgroup\$ – edi9999 Mar 27 '13 at 7:16
1
\$\begingroup\$

This should be O(n)* where n is count($board_id).

$mapped = array_map(function ($id) use ($boardkey_to_values) {
    return array($boardkey_to_values[$id], $id);
}, $board_id);
asort($mapped);
list($min_value, $id) = reset($mapped);
$min_ids = array($id);
while (list($value, $id) = next($mapped)) {
    if ($value == $min_value) {
        $min_ids[] = $id;
    }
    else {
        break;
    }
}

* ignoring the call to asort which is probably O(n log n).

\$\endgroup\$
  • \$\begingroup\$ What exactly does the use keyword do after the parameters of an anonymous function ? \$\endgroup\$ – edi9999 Mar 27 '13 at 7:27
  • 1
    \$\begingroup\$ It allows the anonymous function to access the named variable. Without it the function can only access the local variables and arguments it declares. \$\endgroup\$ – David Harkness Mar 27 '13 at 7:55
0
\$\begingroup\$

You could try doing it this way:

$min_key = null;
asort($boardkey_to_values);

foreach(array_count_values($boardkey_to_values) as $val) {
  $min_key = array_slice( array_keys($boardkey_to_values), $val );
  break;
}

I believe that would accomplish what you're trying to do.

\$\endgroup\$
  • \$\begingroup\$ Your function is very slow compared to mine, because array_slice is slow given the size of the $boardkey_to_values (more than 40 000 entries). And it isn't exactly what I meant (cf edit for the example) \$\endgroup\$ – edi9999 Feb 24 '13 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.