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])

asked Feb 22, 2013 at 14:28
\$\endgroup\$
2
  • \$\begingroup\$ Why is 23 > 19 when they both map to the same value? Shouldn't they be equal? \$\endgroup\$ Commented Mar 26, 2013 at 22:00
  • \$\begingroup\$ Yes you're right 23=19, I have edited my question \$\endgroup\$ Commented Mar 27, 2013 at 7:16

2 Answers 2

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).

answered Mar 26, 2013 at 22:15
\$\endgroup\$
2
  • \$\begingroup\$ What exactly does the use keyword do after the parameters of an anonymous function ? \$\endgroup\$ Commented Mar 27, 2013 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\$ Commented Mar 27, 2013 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.

answered Feb 22, 2013 at 21:04
\$\endgroup\$
1
  • \$\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\$ Commented Feb 24, 2013 at 21:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.